Webpack ProvidePlugin vs externes?
J'explore l'idée de l'utilisation de Webpack avec épine Dorsale.js .
J'ai suivi le guide de démarrage rapide et j'ai une idée générale du fonctionnement de Webpack, mais je ne sais pas comment charger la bibliothèque de dépendances comme jquery / backbone / underscore.
Devraient-ils être chargés en externe avec <script>
ou est-ce quelque chose que Webpack peut gérer comme le shim de RequireJS?
Selon le document webpack : modules de shimming, ProvidePlugin
et externals
semblent être liés à cela (c'est donc bundle!
loader quelque part) mais je ne peux pas savoir quand utiliser lequel.
Merci
3 réponses
C'est possible: vous pouvez inclure des bibliothèques avec un <script>
(c'est-à-dire utiliser une bibliothèque à partir d'un CDN) ou les inclure dans le bundle généré.
Si vous le chargez via la balise <script>
, Vous pouvez utiliser l'option externals
pour permettre d'écrire require(...)
dans vos modules.
Exemple avec la bibliothèque de CDN:
<script src="https://code.jquery.com/jquery-git2.min.js"></script>
// the artifial module "jquery" exports the global var "jQuery"
externals: { jquery: "jQuery" }
// inside any module
var $ = require("jquery");
Exemple avec la bibliothèque incluse dans le bundle:
copy `jquery-git2.min.js` to your local filesystem
// make "jquery" resolve to your local copy of the library
// i. e. through the resolve.alias option
resolve: { alias: { jquery: "/path/to/jquery-git2.min.js" } }
// inside any module
var $ = require("jquery");
Le ProvidePlugin
peut mapper des modules à des variables (libres). Vous pouvez donc définir: "chaque fois que j'utilise la variable (libre) xyz
dans un module, vous (webpack) devez définir xyz
sur require("abc")
."
Exemple sans ProvidePlugin
:
// You need to require underscore before you can use it
var _ = require("underscore");
_.size(...);
Exemple avec ProvidePlugin
:
plugins: [
new webpack.ProvidePlugin({
"_": "underscore"
})
]
// If you use "_", underscore is automatically required
_.size(...)
Résumé:
- bibliothèque de CDN: utilisez la balise
<script>
et l'optionexternals
- Bibliothèque du système de fichiers: incluez la bibliothèque dans le bundle.
(Peut-être modifier
resolve
options pour trouver la bibliothèque) -
externals
: Rendre les variables globales disponibles en tant que module -
ProvidePlugin
: rendre les modules disponibles en tant que variables libres à l'intérieur les modules
Quelque chose de cool à noter est que si vous utilisez le ProvidePlugin
en combinaison avec la propriété externals
, il vous permettra d'avoir jQuery
passé dans votre fermeture de module webpack sans avoir à explicitement require
. Cela peut être utile pour refactorer le code hérité avec beaucoup de fichiers différents faisant référence à $
.
//webpack.config.js
module.exports = {
entry: './index.js',
output: {
filename: '[name].js'
},
externals: {
jquery: 'jQuery'
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
})
]
};
Maintenant dans l'index.js
console.log(typeof $ === 'function');
Aura une sortie compilée avec quelque chose comme ci-dessous passé dans la fermeture webpackBootstrap
:
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function($) {
console.log(typeof $ === 'function');
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1)))
/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {
module.exports = jQuery;
/***/ }
/******/ ])
Par conséquent, vous pouvez voir que $
fait référence au global / window jQuery
à partir du CDN, mais est passé dans la fermeture. Je ne suis pas sûr si c'est une fonctionnalité prévue ou un hack chanceux, mais cela semble bien fonctionner pour mon cas d'utilisation.
Je sais que c'est un ancien post mais j'ai pensé qu'il serait utile de mentionner que le chargeur de script webpack peut également être utile dans ce cas. À partir des documents webpack:
"script: exécute un fichier JavaScript une fois dans un contexte global (comme dans la balise script), les requires ne sont pas analysés."
Http://webpack.github.io/docs/list-of-loaders.html
Https://github.com/webpack/script-loader
J'ai trouvé cela particulièrement utile lors de la migration de build plus ancienne processus qui concattent les fichiers fournisseurs JS et les fichiers d'applications ensemble. Un mot d'avertissement est que le chargeur de script semble fonctionner uniquement en surchargeant require()
et ne fonctionne pas autant que je peux dire en étant spécifié dans un webpack.fichier de configuration. Bien que, beaucoup soutiennent que la surcharge require
est une mauvaise pratique, il peut être très utile pour concéder le script du fournisseur et de l'application en un seul paquet, et en même temps exposer les Globals JS qui ne doivent pas être intégrés dans des bundles webpack supplémentaires. Pour exemple:
require('script!jquery-cookie/jquery.cookie');
require('script!history.js/scripts/bundled-uncompressed/html4+html5/jquery.history');
require('script!momentjs');
require('./scripts/main.js');
Cela ferait $.cookie, historique et moment globalement disponibles à l'intérieur et à l'extérieur de ce bundle, et regrouper ces bibliothèques de fournisseur avec le principal.script js et tous ses fichiers require
D.
Aussi, utile avec cette technique est:
resolve: {
extensions: ["", ".js"],
modulesDirectories: ['node_modules', 'bower_components']
},
plugins: [
new webpack.ResolverPlugin(
new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
)
]
Qui utilise Bower, examinera le fichier main
dans chaque paquet de bibliothèques require
D.json. Dans l'exemple ci-dessus, de l'Histoire.js n'a pas de fichier main
spécifié, donc le chemin d'accès au fichier est nécessaire.