Entiendo la esencia general de que CommonsChunkPlugin
examina todos los puntos de entrada, comprueba si hay paquetes / dependencias comunes entre ellos y los separa en su propio paquete.
Entonces, supongamos que tengo la siguiente configuración:
...
enrty : {
entry1 : 'entry1.js', //which has 'jquery' as a dependency
entry2 : 'entry2.js', //which has 'jquery as a dependency
vendors : [
'jquery',
'some_jquery_plugin' //which has 'jquery' as a dependency
]
},
output: {
path: PATHS.build,
filename: '[name].bundle.js'
}
...
Si empaqueto sin usar CommonsChunkPlugin
Terminaré con 3 nuevos archivos de paquete:
entry1.bundle.js
el cual contiene el código completo deentry1.js
yjquery
y contiene su propio tiempo de ejecuciónentry2.bundle.js
el cual contiene el código completo deentry2.js
yjquery
y contiene su propio tiempo de ejecuciónvendors.bundle.js
el cual contiene el código completo dejquery
ysome_jquery_plugin
y contiene su propio tiempo de ejecución
Obviamente, esto es malo porque potencialmente cargaré jquery
3 veces en la página, por lo que no queremos eso.
Si empaqueto usando CommonsChunkPlugin
Dependiendo de los argumentos que pase a CommonsChunkPlugin
cualquiera de los siguientes sucederá:
CASO 1: Si apruebo
{ name : 'commons' }
, terminaré con los siguientes archivos de paquete:entry1.bundle.js
que contiene el código completo deentry1.js
, un requisito parajquery
y no contiene el tiempo de ejecuciónentry2.bundle.js
que contiene el código completo deentry2.js
, un requisito parajquery
y no contiene el tiempo de ejecuciónvendors.bundle.js
que contiene el código completo desome_jquery_plugin
, un requisito parajquery
y no contiene el tiempo de ejecucióncommons.bundle.js
que contiene el código completojquery
y contiene el tiempo de ejecución
De esta manera, terminamos con algunos paquetes más pequeños en general y el tiempo de ejecución está contenido en el
commons
paquete. Bastante bien, pero no ideal.CASO 2: Si apruebo
{ name : 'vendors' }
, terminaré con los siguientes archivos de paquete:entry1.bundle.js
que contiene el código completo deentry1.js
, un requisito parajquery
y no contiene el tiempo de ejecuciónentry2.bundle.js
que contiene el código completo deentry2.js
, un requisito parajquery
y no contiene el tiempo de ejecuciónvendors.bundle.js
que contiene el código completo dejquery
ysome_jquery_plugin
y contiene el tiempo de ejecución.
De esta manera, nuevamente, terminamos con algunos paquetes más pequeños en general, pero el tiempo de ejecución ahora está contenido en el
vendors
paquete. Es un poco peor que el caso anterior, ya que el tiempo de ejecución ahora está en elvendors
paquete.CASO 3: Si apruebo
{ names : ['vendors', 'manifest'] }
, terminaré con los siguientes archivos de paquete:entry1.bundle.js
que contiene el código completo deentry1.js
, un requisito parajquery
y no contiene el tiempo de ejecuciónentry2.bundle.js
que contiene el código completo deentry2.js
, un requisito parajquery
y no contiene el tiempo de ejecuciónvendors.bundle.js
que contiene el código completo dejquery
ysome_jquery_plugin
no contiene el tiempo de ejecuciónmanifest.bundle.js
que contiene requisitos para todos los demás paquetes y contiene el tiempo de ejecución
De esta manera, terminamos con algunos paquetes más pequeños en general y el tiempo de ejecución está contenido en el
manifest
paquete. Este es el caso ideal.
Lo que no entiendo / no estoy seguro de entender
En el CASO 2, ¿por qué terminamos con el
vendors
paquete que contiene tanto el código común (jquery
) como lo que queda de lavendors
entrada (some_jquery_plugin
)? Según tengo entendido, lo queCommonsChunkPlugin
hizo aquí fue que reunió el código común (jquery
), y dado que lo obligamos avendors
enviarlo al paquete, "fusionó" el código común en elvendors
paquete (que ahora solo contenía el código desome_jquery_plugin
). Por favor confirme o explique.En el CASO 3 no entiendo qué pasó cuando pasamos
{ names : ['vendors', 'manifest'] }
al plugin. ¿Por qué / cómo sevendors
mantuvo intacto el paquete, que contiene ambosjquery
ysome_jquery_plugin
, cuándojquery
es claramente una dependencia común, y por qué semanifest.bundle.js
creó el archivo generado de la forma en que se creó (requiriendo todos los demás paquetes y conteniendo el tiempo de ejecución)?
fuente
Respuestas:
Así es como el
CommonsChunkPlugin
funciona.Un fragmento común "recibe" los módulos compartidos por varios fragmentos de entrada. Un buen ejemplo de una configuración compleja se puede encontrar en el repositorio de Webpack .
Se
CommonsChunkPlugin
ejecuta durante la fase de optimización de Webpack, lo que significa que opera en la memoria, justo antes de que los fragmentos se sellen y escriban en el disco.Cuando se definen varios fragmentos comunes, se procesan en orden. En su caso 3, es como ejecutar el complemento dos veces. Pero tenga en cuenta que
CommonsChunkPlugin
puede tener una configuración más compleja (minSize, minChunks, etc.) que afecta la forma en que se mueven los módulos.CASO 1:
entry
fragmentos (entry1
,entry2
yvendors
).commons
fragmento como un fragmento común.commons
fragmento común (dado que el fragmento no existe, se crea):entry1
,entry2
yvendors
usojquery
de modo que el módulo se retira de estos trozos y se añade a lacommons
porción.commons
fragmento se marca como unentry
fragmento, mientras que los fragmentosentry1
,entry2
y novendors
se marcan comoentry
.commons
fragmento es unentry
fragmento, contiene el tiempo de ejecución y eljquery
módulo.CASO 2:
entry
fragmentos (entry1
,entry2
yvendors
).vendors
fragmento como un fragmento común.vendors
fragmento común:entry1
yentry2
usajquery
para que el módulo se elimine de estos fragmentos (tenga en cuenta que no se agrega alvendors
fragmentovendors
fragmento ya lo contiene).vendors
fragmento se marca como unentry
fragmento mientras que los fragmentosentry1
y noentry2
se marcan comoentry
.vendors
fragmento es unentry
fragmento, contiene el tiempo de ejecución y los módulosjquery
/jquery_plugin
.CASO 3:
entry
fragmentos (entry1
,entry2
yvendors
).vendors
fragmento y elmanifest
fragmento como fragmentos comunes.manifest
fragmento ya que no existe.vendors
fragmento común:entry1
yentry2
usejquery
para que el módulo se elimine de estos fragmentos (tenga en cuenta que no se agrega alvendors
fragmento porque elvendors
fragmento ya lo contiene).vendors
fragmento se marca como unentry
fragmento mientras que los fragmentosentry1
y noentry2
se marcan comoentry
.manifest
fragmento común (dado que el fragmento no existe, se crea):manifest
fragmento se marca comoentry
fragmento mientras queentry1
,entry2
y novendors
se marcan comoentry
.manifest
fragmento es unentry
fragmento, contiene el tiempo de ejecución.Espero eso ayude.
fuente
{ names : ['vendors', 'manifest'] }
es como ejecutarlo dos veces, una vez con{ name : 'vendors' }
y una vez con{ name : 'manifest' }
, ¿correcto? 3) Cuando decimos "El complemento procesa un fragmento común" queremos decir que crea el contenido que escupirá en elbundle.js
archivo, en la memoria, ¿correcto? 4) Hasta que se "procesa todos los fragmentos comunes", no se ha escrito ninguna salida en un archivo, todo está en la memoriaentry1.js
yentry2.js
teníamos otro archivo común entre ellos, además deljquery
archivo, llamémosloownLib.js
. En el CASO 2 y el CASO 3,ownLib.js
¿terminaría en elvendors.bundle.js
correcto? ¿Cómo haría para que los archivos comunes que no sean archivos de proveedores se separen en su propio fragmento, aparte delvendors
fragmento? Perdón por molestarte, pero todavía estoy aprendiendo a usar el paquete webownLib.js
se colocaría en el primer trozo común. Si se quiere recoger las dependencias comunes en otro chunck, usted tiene que pasar algo como esto:{ names : ['common', 'vendors', 'manifest'] }
.