javascript - online - Solución simple para compartir módulos cargados a través de NPM a través de múltiples paquetes de Browserify o Webpack
grunt browserify (3)
Con el paquete web usarías múltiples puntos de entrada y el CommonChunkPlugin .
Tomado de los documentos webpack :
Para dividir su aplicación en 2 archivos, digamos app.js
y vendor.js
, puede requerir los archivos de proveedores en vendor.js
. Luego pase este nombre al CommonChunkPlugin como se muestra a continuación.
module.exports = {
entry: {
app: "./app.js",
vendor: ["jquery", "underscore", ...],
},
output: {
filename: "bundle.js"
},
plugins: [
new webpack.optimize.CommonsChunkPlugin(
/* chunkName= */"vendor",
/* filename= */"vendor.bundle.js"
)
]
};
Esto eliminará todos los módulos de la parte del proveedor de la parte de la aplicación. bundle.js
ahora contendrá solo el código de tu aplicación, sin ninguna de sus dependencias. Estos están en vendor.bundle.js
.
En su página HTML, cargue vendor.bundle.js
antes de bundle.js
.
<script src="vendor.bundle.js"></script>
<script src="bundle.js"></script>
Saque mi cabello aquí en busca de una solución simple para compartir código, requerido a través de NPM, a través de múltiples paquetes Browserify o Webpack. Pensando, ¿existe tal cosa como un archivo "puente"?
Esto no se debe al tiempo de compilación (soy consciente de watchify) sino al deseo de extraer todas mis vendor.js
específicas de proveedores en vendor.js
para mantener el tamaño de archivo de mi app.js
y no bloquear el navegador con una gran cantidad sourcemaps. Además, me parece más limpio si surge la necesidad de ver los js compilados. Y entonces:
// vendor.js
require(''react'');
require(''lodash'');
require(''other-npm-module'');
require(''another-npm-module'');
Es muy importante que el código se cargue desde NPM en lugar de Bower, o que se guarde en el directorio de algún "proveedor" para poder importarlo a través de una ruta relativa e identificarlo a través de un shim. Me gustaría mantener todas las referencias de la biblioteca extraídas a través de NPM, excepto mi fuente de aplicación real.
En app.js
todo mi código fuente y, a través de la matriz externals
, excluyo de la compilación las bibliotecas de proveedores enumeradas anteriormente:
// app.js
var React = require(''react'');
var _ = require(''lodash'');
var Component = React.createClass()
// ...
Y luego en index.html
, necesito ambos archivos
// index.html
<script src=''vendor.js''></script>
<script src=''app.js''></script>
Con Browserify o Webpack, ¿cómo puedo hacer que app.js
pueda "ver" en los módulos cargados a través de npm? Soy consciente de crear un paquete con elementos externos y luego hacer referencia al archivo directo (en, por ejemplo, node_modules
) a través de un alias, pero espero encontrar una solución más automática y menos "Require.js".
Básicamente, me pregunto si es posible unir ambos para que app.js
pueda buscar en vendor.js
para resolver las dependencias. Esto parece una operación simple y directa, pero parece que no puedo encontrar una respuesta en ninguna parte de esta web amplia y amplia.
¡Gracias!
La lista de todos los archivos / módulos de proveedores y el uso de CommonChunkPlugin es la manera recomendada. Esto se vuelve bastante tedioso y propenso a errores.
Considere estos módulos NPM: fastclick
y mprogress
. Dado que no han adoptado el formato del módulo CommonJS , debe darle una mano al paquete web, como esto:
require(''imports?define=>false!fastclick'')(document.body);
require(''mprogress/mprogress.min.css'');
var Mprogress = require(''mprogress/mprogress.min.js''),
Ahora, asumiendo que querría tanto fastclick
como mprogress
en su parte de proveedor, probablemente probaría esto:
module.exports = {
entry: {
app: "./app.js",
vendor: ["fastclick", "mprogress", ...]
Por desgracia, no funciona. Necesitas emparejar las llamadas para require()
:
module.exports = {
entry: {
app: "./app.js",
vendor: [
"imports?define=>false!fastclick",
"mprogress/mprogress.min.css",
"mprogress/mprogress.min.js",
...]
Se vuelve viejo, incluso con algunos trucos de resolve.alias
. Aquí está mi solución. CommonChunkPlugin le permite especificar una devolución de llamada que devolverá si desea o no que se incluya un módulo en la parte del proveedor. Si su propio código fuente está en un directorio src
específico, y el resto está en el directorio node_modules
, simplemente rechace los módulos en función de su ruta:
var node_modules_dir = path.join(__dirname, ''node_modules''),
app_dir = path.join(__dirname, ''src'');
module.exports = {
entry: {
app: "./app.js",
},
output: {
filename: "bundle.js"
},
plugins: [
new webpack.optimize.CommonsChunkPlugin(
/* chunkName= */"vendor",
/* filename= */"vendor.bundle.js"
function (module, count) {
return module.resource && module.resource.indexOf(app_dir) === -1;
}
)
]
};
Donde module.resource
es la ruta al módulo que se está considerando. También puede hacer lo contrario e incluir solo el módulo si está dentro de node_modules_dir
, es decir:
return module.resource && module.resource.indexOf(node_modules_dir) === 0;
pero en mi situación, preferiría decir: " ponga todo lo que no esté en mi árbol fuente en una porción de proveedor ".
Espero que ayude.
// vendor anything coming from node_modules
minChunks: module => /node_modules/.test(module.resource)
Fuente: https://github.com/webpack/webpack/issues/2372#issuecomment-213149173