Gestión de la dependencia del plugin de jQuery en webpack
Estoy usando Webpack en mi aplicación, en la que creo dos puntos de entrada - bundle.js para todos mis archivos/códigos JavaScript, y vendors.js para todas las librerías como jQuery y React. ¿Qué hago para usar plugins que tienen jQuery como sus dependencias y quiero tenerlos también en vendors.js? ¿Y si esos plugins tienen múltiples dependencias?
Actualmente estoy intentando utilizar este plugin de jQuery - https://github.com/mbklein/jquery-elastic. La documentación de Webpack menciona providePlugin e imports-loader. He utilizado providePlugin, pero el objeto jQuery sigue sin estar disponible. Así es como se ve mi webpack.config.js-
var webpack = require('webpack');
var bower_dir = __dirname + '/bower_components';
var node_dir = __dirname + '/node_modules';
var lib_dir = __dirname + '/public/js/libs';
var config = {
addVendor: function (name, path) {
this.resolve.alias[name] = path;
this.module.noParse.push(new RegExp(path));
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jquery: "jQuery",
"window.jQuery": "jquery"
}),
new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.js', Infinity)
],
entry: {
app: ['./public/js/main.js'],
vendors: ['react','jquery']
},
resolve: {
alias: {
'jquery': node_dir + '/jquery/dist/jquery.js',
'jquery.elastic': lib_dir + '/jquery.elastic.source.js'
}
},
output: {
path: './public/js',
filename: 'bundle.js'
},
module: {
loaders: [
{ test: /\.js$/, loader: 'jsx-loader' },
{ test: /\.jquery.elastic.js$/, loader: 'imports-loader' }
]
}
};
config.addVendor('react', bower_dir + '/react/react.min.js');
config.addVendor('jquery', node_dir + '/jquery/dist/jquery.js');
config.addVendor('jquery.elastic', lib_dir +'/jquery.elastic.source.js');
module.exports = config;
Pero a pesar de esto, sigue arrojando un error en la consola del navegador:
Uncaught ReferenceError: jQuery is not defined
Del mismo modo, cuando utilizo el cargador de importaciones, arroja un error,
require no está definido'
en esta línea:
var jQuery = require("jquery")
Sin embargo, podría usar el mismo plugin cuando no lo añado a mi archivo vendors.js y en su lugar lo requiero de la manera normal de AMD como incluyo mis otros archivos de código JavaScript, como-
define(
[
'jquery',
'react',
'../../common-functions',
'../../libs/jquery.elastic.source'
],function($,React,commonFunctions){
$("#myInput").elastic() //It works
});
Pero esto no es lo que quiero hacer, ya que esto significaría que jquery.elastic.source.js se incluye junto con mi código JavaScript en bundle.js, y quiero que todos mis plugins jQuery estén en el paquete vendors.js. Entonces, ¿cómo puedo hacer para lograr esto?
Usted ha mezclado diferentes enfoques sobre cómo incluir los módulos de proveedores heredados. Así es como yo lo abordaría:
1. Preferir CommonJS/AMD sin minificar sobre
dist
.La mayoría de los módulos enlazan la versión
dist
en el campomain
de supackage.json
. Aunque esto es útil para la mayoría de los desarrolladores, para webpack es mejor poner un alias a la versiónsrc
porque de esta manera webpack es capaz de optimizar mejor las dependencias (por ejemplo, cuando se utiliza elDedupePlugin
).Sin embargo, en la mayoría de los casos la versión
dist
también funciona bien.2. Utilice el
ProvidePlugin
para inyectar globales implícitosLa mayoría de los módulos heredados dependen de la presencia de globals específicos, como los plugins de jQuery hacen con
$
ojQuery
. En este caso puedes configurar webpack para que añadavar $ = require("jquery")
cada vez que encuentre el identificador global$
.3. Utilice el imports-loader para configurar
this
Algunos módulos heredados dependen de que
this
sea el objetowindow
. Esto se convierte en un problema cuando el módulo se ejecuta en un contexto CommonJS dondethis
es igual amodule.exports
. En este caso puedes anularthis
con el imports-loader.Ejecuta
npm i imports-loader --save-dev
y luegoEl imports-loader también se puede utilizar para inyectar manualmente variables de todo tipo. Pero la mayoría de las veces el
ProvidePlugin
es más útil cuando se trata de globales implícitos.4. Utilice el imports-loader para desactivar AMD
Hay módulos que soportan diferentes estilos de módulos, como AMD, CommonJS y legacy. Sin embargo, la mayoría de las veces primero comprueban la existencia de
define
y luego utilizan algún código peculiar para exportar las propiedades. En estos casos, podría ayudar forzar la ruta de CommonJS estableciendodefine = false
.5. Utilice el script-loader para importar globalmente los scripts
Si no te importan las variables globales y sólo quieres que los scripts heredados funcionen, también puedes usar el script-loader. Este ejecuta el módulo en un contexto global, igual que si los hubieras incluido a través de la etiqueta
<script>
.6. Utilice
noParse
para incluir discos grandesCuando no hay una versión AMD/CommonJS del módulo y quieres incluir el
dist
, puedes marcar este módulo comonoParse
. Entonces webpack simplemente incluirá el módulo sin analizarlo, lo que puede utilizarse para mejorar el tiempo de compilación. Esto significa que cualquier característica que requiera el AST, como elProvidePlugin
, no funcionará.Para el acceso global a jquery existen varias opciones. En mi proyecto webpack más reciente, quería un acceso global a jquery, así que añadí lo siguiente a las declaraciones de mis plugins:
Esto significa que jquery es accesible desde el código fuente de JavaScript a través de las referencias globales $ y jQuery.
Por supuesto, también es necesario haber instalado jquery a través de npm:
Para un ejemplo de trabajo de este enfoque por favor siéntase libre de fork mi aplicación en github
No sé si entiendo muy bien lo que tratas de hacer, pero tuve que usar plugins de jQuery que requerían que jQuery estuviera en el contexto global (ventana) y puse lo siguiente en mi
entry.js
:Luego solo tengo que requerir donde quiera el
jqueryplugin.min.js
ywindow.$
se extiende con el plugin como se esperaba.