backbone.js - script - ¿Webpack ProvidePlugin vs Externals?
webpack node externals (3)
Algo interesante de notar es que si usas el ProvidePlugin
en combinación con la propiedad externals
, te permitirá tener jQuery
pasado al cierre del módulo webpack sin tener que solicitarlo explícitamente. Esto puede ser útil para refactorizar el código heredado con una gran cantidad de archivos diferentes que hacen referencia a $
.
//webpack.config.js
module.exports = {
entry: ''./index.js'',
output: {
filename: ''[name].js''
},
externals: {
jquery: ''jQuery''
},
plugins: [
new webpack.ProvidePlugin({
$: ''jquery'',
})
]
};
ahora en index.js
console.log(typeof $ === ''function'');
tendrá un resultado compilado con algo como lo que se pasa a continuación en el cierre de 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;
/***/ }
/******/ ])
Por lo tanto, puede ver que $
hace referencia al global / window jQuery
del CDN, pero se está transfiriendo al cierre. No estoy seguro de si esta es la funcionalidad prevista o un hack de la suerte, pero parece funcionar bien para mi caso de uso.
Estoy explorando la idea de usar Webpack con Backbone.js .
He seguido la guía de inicio rápido y tengo una idea general de cómo funciona Webpack, pero no tengo claro cómo cargar la biblioteca de dependencias como jquery / backbone / underscore.
¿Deberían cargarse externamente con <script>
o es algo que Webpack puede manejar como el shim de RequireJS?
De acuerdo con el documento webpack: los módulos de ProvidePlugin
, ProvidePlugin
y externals
parecen estar relacionados con esto (por lo que el bundle!
es loader en alguna parte) pero no puedo imaginar cuándo usarlos.
Gracias
Es posible: puede incluir bibliotecas con un <script>
(es decir, para usar una biblioteca desde un CDN) o incluirlas en el paquete generado.
Si lo carga a través de la etiqueta <script>
, puede usar la opción externals
para permitir escribir require(...)
en sus módulos.
Ejemplo con la biblioteca 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");
Ejemplo con la biblioteca incluida en el paquete:
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");
ProvidePlugin
puede asignar módulos a variables (gratuitas). De modo que podría definir: "Cada vez que uso la variable (gratuita) xyz
dentro de un módulo, usted (paquete web) debe establecer xyz
para require("abc")
".
Ejemplo sin ProvidePlugin
:
// You need to require underscore before you can use it
var _ = require("underscore");
_.size(...);
Ejemplo con ProvidePlugin
:
plugins: [
new webpack.ProvidePlugin({
"_": "underscore"
})
]
// If you use "_", underscore is automatically required
_.size(...)
Resumen:
- Biblioteca de CDN: use la etiqueta
<script>
yexternals
opciónexternals
- Biblioteca del sistema de archivos: incluya la biblioteca en el paquete. (Tal vez modifique las opciones de
resolve
para encontrar la biblioteca) -
externals
: hacer vars globales disponibles como módulo -
ProvidePlugin
: Haga que los módulos estén disponibles como variables libres dentro de los módulos
Sé que esta es una publicación anterior, pero pensé que sería útil mencionar que el gestor de script de webpack también puede ser útil en este caso. De los documentos de la carpeta web:
"script: Ejecuta un archivo JavaScript una vez en contexto global (como en la etiqueta script), no se analiza".
http://webpack.github.io/docs/list-of-loaders.html
https://github.com/webpack/script-loader
Esto me pareció particularmente útil al migrar procesos de compilación más antiguos que combinan los archivos del proveedor JS y los archivos de la aplicación. Una palabra de advertencia es que el gestor de scripts parece funcionar solo a través de la sobrecarga require()
y no funciona tan lejos como puedo decir al ser especificado dentro de un archivo webpack.config. Aunque muchos argumentan que la sobrecarga require
una mala práctica, puede ser bastante útil para concatar el script de la aplicación y el proveedor en un solo paquete, y al mismo tiempo exponer JS Globals que no tienen que ser recortados en paquetes adicionales de webpack. Por ejemplo:
require(''script!jquery-cookie/jquery.cookie'');
require(''script!history.js/scripts/bundled-uncompressed/html4+html5/jquery.history'');
require(''script!momentjs'');
require(''./scripts/main.js'');
Esto haría que $ .cookie, History y moment globalmente estén disponibles dentro y fuera de este paquete, y agrupe estas libs de proveedores con el script main.js y todo lo que require
d archivos.
Además, útil con esta técnica es:
resolve: {
extensions: ["", ".js"],
modulesDirectories: [''node_modules'', ''bower_components'']
},
plugins: [
new webpack.ResolverPlugin(
new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
)
]
que está usando Bower, mirará el archivo main
en cada paquete require
libraries d. json. En el ejemplo anterior, History.js no tiene un archivo main
especificado, por lo que la ruta al archivo es necesaria.