Entiendo la esencia general de que CommonsChunkPluginexamina 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.jsel cual contiene el código completo deentry1.jsyjqueryy contiene su propio tiempo de ejecuciónentry2.bundle.jsel cual contiene el código completo deentry2.jsyjqueryy contiene su propio tiempo de ejecuciónvendors.bundle.jsel cual contiene el código completo dejqueryysome_jquery_pluginy contiene su propio tiempo de ejecución
Obviamente, esto es malo porque potencialmente cargaré jquery3 veces en la página, por lo que no queremos eso.
Si empaqueto usando CommonsChunkPlugin
Dependiendo de los argumentos que pase a CommonsChunkPlugincualquiera de los siguientes sucederá:
CASO 1: Si apruebo
{ name : 'commons' }, terminaré con los siguientes archivos de paquete:entry1.bundle.jsque contiene el código completo deentry1.js, un requisito parajqueryy no contiene el tiempo de ejecuciónentry2.bundle.jsque contiene el código completo deentry2.js, un requisito parajqueryy no contiene el tiempo de ejecuciónvendors.bundle.jsque contiene el código completo desome_jquery_plugin, un requisito parajqueryy no contiene el tiempo de ejecucióncommons.bundle.jsque contiene el código completojqueryy 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
commonspaquete. Bastante bien, pero no ideal.CASO 2: Si apruebo
{ name : 'vendors' }, terminaré con los siguientes archivos de paquete:entry1.bundle.jsque contiene el código completo deentry1.js, un requisito parajqueryy no contiene el tiempo de ejecuciónentry2.bundle.jsque contiene el código completo deentry2.js, un requisito parajqueryy no contiene el tiempo de ejecuciónvendors.bundle.jsque contiene el código completo dejqueryysome_jquery_pluginy 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
vendorspaquete. Es un poco peor que el caso anterior, ya que el tiempo de ejecución ahora está en elvendorspaquete.CASO 3: Si apruebo
{ names : ['vendors', 'manifest'] }, terminaré con los siguientes archivos de paquete:entry1.bundle.jsque contiene el código completo deentry1.js, un requisito parajqueryy no contiene el tiempo de ejecuciónentry2.bundle.jsque contiene el código completo deentry2.js, un requisito parajqueryy no contiene el tiempo de ejecuciónvendors.bundle.jsque contiene el código completo dejqueryysome_jquery_pluginno contiene el tiempo de ejecuciónmanifest.bundle.jsque 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
manifestpaquete. Este es el caso ideal.
Lo que no entiendo / no estoy seguro de entender
En el CASO 2, ¿por qué terminamos con el
vendorspaquete que contiene tanto el código común (jquery) como lo que queda de lavendorsentrada (some_jquery_plugin)? Según tengo entendido, lo queCommonsChunkPluginhizo aquí fue que reunió el código común (jquery), y dado que lo obligamos avendorsenviarlo al paquete, "fusionó" el código común en elvendorspaquete (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 sevendorsmantuvo intacto el paquete, que contiene ambosjqueryysome_jquery_plugin, cuándojqueryes claramente una dependencia común, y por qué semanifest.bundle.jscreó 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
CommonsChunkPluginfunciona.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
CommonsChunkPluginejecuta 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
CommonsChunkPluginpuede tener una configuración más compleja (minSize, minChunks, etc.) que afecta la forma en que se mueven los módulos.CASO 1:
entryfragmentos (entry1,entry2yvendors).commonsfragmento como un fragmento común.commonsfragmento común (dado que el fragmento no existe, se crea):entry1,entry2yvendorsusojqueryde modo que el módulo se retira de estos trozos y se añade a lacommonsporción.commonsfragmento se marca como unentryfragmento, mientras que los fragmentosentry1,entry2y novendorsse marcan comoentry.commonsfragmento es unentryfragmento, contiene el tiempo de ejecución y eljquerymódulo.CASO 2:
entryfragmentos (entry1,entry2yvendors).vendorsfragmento como un fragmento común.vendorsfragmento común:entry1yentry2usajquerypara que el módulo se elimine de estos fragmentos (tenga en cuenta que no se agrega alvendorsfragmentovendorsfragmento ya lo contiene).vendorsfragmento se marca como unentryfragmento mientras que los fragmentosentry1y noentry2se marcan comoentry.vendorsfragmento es unentryfragmento, contiene el tiempo de ejecución y los módulosjquery/jquery_plugin.CASO 3:
entryfragmentos (entry1,entry2yvendors).vendorsfragmento y elmanifestfragmento como fragmentos comunes.manifestfragmento ya que no existe.vendorsfragmento común:entry1yentry2usejquerypara que el módulo se elimine de estos fragmentos (tenga en cuenta que no se agrega alvendorsfragmento porque elvendorsfragmento ya lo contiene).vendorsfragmento se marca como unentryfragmento mientras que los fragmentosentry1y noentry2se marcan comoentry.manifestfragmento común (dado que el fragmento no existe, se crea):manifestfragmento se marca comoentryfragmento mientras queentry1,entry2y novendorsse marcan comoentry.manifestfragmento es unentryfragmento, 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.jsarchivo, 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.jsyentry2.jsteníamos otro archivo común entre ellos, además deljqueryarchivo, llamémosloownLib.js. En el CASO 2 y el CASO 3,ownLib.js¿terminaría en elvendors.bundle.jscorrecto? ¿Cómo haría para que los archivos comunes que no sean archivos de proveedores se separen en su propio fragmento, aparte delvendorsfragmento? Perdón por molestarte, pero todavía estoy aprendiendo a usar el paquete webownLib.jsse 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'] }.