web-dev-qa-db-fra.com

Puis-je utiliser une importation de module ES6 / 2015 pour définir une référence dans la portée «globale»?

J'ai cette situation où j'essaie d'importer une bibliothèque existante, que j'appellerai troublesome (en utilisant Webpack/Babel FWIW) et elle a une référence globale à jQuery dans laquelle je suis essayer de résoudre en utilisant la syntaxe du module.

J'ai importé jquery avec succès dans la portée "locale" d'un module, via:

import jQuery from 'jquery'

alors j'ai essayé:

import jQuery from 'jquery'    
import 'troublesome'

mais peut-être pas surprenant, je reçois quelque chose comme jQuery is not a function repoussé de troublesome.js

J'ai également essayé ceci:

System.import('jquery')
.then(jQuery => {
    window.jQuery = jQuery
})
import 'troublesome'

mais il s'avère que System.import fait partie de la soi-disant spécification 'module-loader', qui a été tirée de la spécification es6/2015, donc elle n'est pas fournie par Babel. Il y a poly-fill , mais Webpack ne pourrait pas gérer les importations dynamiques effectuées via des appels à System.import en tous cas.

mais ... si j'appelle les fichiers de script dans index.html comme ceci:

<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/troublesome/troublesome.js"></script>
<script src="the-rest-of-my-js.js"></script>

la référence à jQuery est résolue dans troublesome.js et les choses vont bien, mais je préférerais éviter la route des balises de script car webpack ne les gère pas.

Quelqu'un peut-il recommander une stratégie décente pour faire face à des scénarios comme celui-ci?

mise à jour

avec quelques conseils de @ TN1ck, j'ai finalement pu identifier une solution centrée sur Webpack, en utilisant imports-loader

La configuration de cette solution ressemble à ceci:

  //...
  module: {
    loaders: [
      //...
      {
        test: require.resolve('troublesome'),
        loader: "imports?jQuery=jquery,$=jquery"
      }
    ]
  }
34
tony_k

Le module de calage est la voie à suivre: http://webpack.github.io/docs/shimming-modules.html

Je cite la page:

plugin ProviderPlugin

Ce plugin rend un module disponible en tant que variable dans chaque module. Le module n'est requis que si vous utilisez la variable.

Exemple: rendre $ et jQuery disponibles dans chaque module sans écrire require("jquery").

new webpack.ProvidePlugin({
  $: "jquery",
  jQuery: "jquery",
  "window.jQuery": "jquery"
})

Pour l'utiliser avec votre webpack-config, ajoutez simplement cet objet à un tableau appelé plugins dans la configuration:

// the plugins we want to use 
var plugins = [
   new webpack.ProvidePlugin({
      $: "jquery",
      jQuery: "jquery",
      "window.jQuery": "jquery"
   })
];

// this is your webpack-config
module.exports = {
    entry: ...,
    output: ...,
    module: ...,
    plugins: plugins
}
16
TN1ck

Pour es6/2015, j'ai fait ce qui suit.

import {jsdom} from 'jsdom';
import jQuery from 'jquery';
var window = jsdom(undefined, {}).defaultView;
var $ = jQuery(window);
//window.jQuery = $; //probably not needed but it's there if something wrong
//window.$ = $;//probably not needed but it's there if something wrong

Ensuite, vous pouvez l'utiliser comme d'habitude

var text = $('<div />').text('hello world!!!').text();
console.log(text);

J'espère que cela t'aides.

2
Val

L'importation de jQuery dans votre module ne le rend pas disponible pour 'troublesome'. Au lieu de cela, vous pouvez créer un module de wrapper fin pour 'troublesome' qui fournit jQuery et tout autre "global" requis.

troublesome-module.js:

// Bring jQuery into scope for troublesome.
import jQuery from 'jquery';
// Import any other 'troublesome'-assumed globals.

// Paste or have build tool interpolate existing troublesome.js code here.

Ensuite, dans votre code, vous devriez pouvoir

import 'troublesome-module';
0
Noah Freitas

J'ai eu un problème similaire en utilisant jspm et des dygraphes. La façon dont je l'ai résolu était d'utiliser le chargement dynamique comme vous avez essayé d'utiliser System.import mais l'important était de charger en chaîne chaque "pièce" consécutive en utilisant System.import à nouveau dans le gestionnaire de promesse onfulfillment (puis) ​​après avoir défini la variable d'espace de noms globale. Dans mon scénario, je devais en fait avoir plusieurs étapes d'importation séparées entre then gestionnaires.

La raison pour laquelle cela n'a pas fonctionné avec jspm, et probablement pourquoi cela n'a pas fonctionné pour vous aussi, c'est que le import ... from ... la syntaxe est évaluée avant tout code, et certainement avant System.import lequel de async.

Dans votre cas, cela pourrait être aussi simple que:

import jQuery from 'jquery';

window.jQuery = jQuery;
System.import('troublesome').then(troublesome => {
 // Do something with it...
});

Notez également que la recommandation de chargeur de module System a été omise de la spécification ES6 finale et qu'une nouvelle spécification de chargeur est en cours de rédaction.

0
Amit
  1. courir npm install import-loader.
  2. remplacer import 'troublesome' avec import 'imports?jQuery=jquery,$=jquery!troublesome.

À mon avis, c'est la solution la plus simple à votre question. Elle est similaire à la réponse que vous avez écrite dans votre question @ TN1ck, mais sans altérer la configuration de votre webpack. Pour plus de lecture, voir: https://github.com/webpack/imports-loader

0
thisissami

Le calage est très bien et il existe différentes façons de résoudre ce problème, mais selon ma réponse ici , le plus simple est en fait de revenir à l'utilisation de require pour le chargement de la bibliothèque qui nécessite la dépendance globale - alors juste assurez-vous que votre fenêtre. l'affectation est avant cette déclaration, et ils sont tous les deux après vos autres importations, et votre commande doit rester comme prévu. Le problème est dû au fait que les importations de levage Babel sont exécutées avant tout autre code.

0
Ben Logan