splitchunksplugin splitchunks removed plugin optimize has example chunk been javascript webpack bundle webpack-plugin commonschunkplugin

javascript - splitchunks - ¿Alguien puede explicar el CommonsChunkPlugin de Webpack?



webpack vendor chunk (1)

Tengo la CommonsChunkPlugin 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 hago un paquete sin usar CommonsChunkPlugin

Terminaré con 3 nuevos paquetes de archivos:

  • entry1.bundle.js que contiene el código completo de entry1.js y jquery y contiene su propio tiempo de ejecución
  • entry2.bundle.js que contiene el código completo de entry2.js y jquery y contiene su propio tiempo de ejecución
  • vendors.bundle.js que contiene el código completo de jquery y some_jquery_plugin y contiene su propio tiempo de ejecución

Esto obviamente es malo porque potencialmente jquery 3 veces en la página, por lo que no queremos eso.

Si hago un paquete usando CommonsChunkPlugin

Dependiendo de los argumentos que le pase a CommonsChunkPlugin cualquiera de los siguientes:

  • CASO 1: si paso { name : ''commons'' } terminaré con los siguientes archivos de paquete:

    • entry1.bundle.js que contiene el código completo de entry1.js , un requisito para jquery y no contiene el tiempo de ejecución
    • entry2.bundle.js que contiene el código completo de entry2.js , un requisito para jquery y no contiene el tiempo de ejecución
    • vendors.bundle.js que contiene el código completo de some_jquery_plugin , un requisito para jquery y no contiene el tiempo de ejecución
    • commons.bundle.js que contiene el código completo de jquery 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 paquete commons . Bastante bien pero no ideal.

  • CASO 2: Si paso { name : ''vendors'' } terminaré con los siguientes archivos de paquete:

    • entry1.bundle.js que contiene el código completo de entry1.js , un requisito para jquery y no contiene el tiempo de ejecución
    • entry2.bundle.js que contiene el código completo de entry2.js , un requisito para jquery y no contiene el tiempo de ejecución
    • vendors.bundle.js que contiene el código completo de jquery y some_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 paquete de vendors . Es un poco peor que el caso anterior, ya que el tiempo de ejecución ahora está en el paquete de vendors .

  • CASO 3: si paso { names : [''vendors'', ''manifest''] } terminaré con los siguientes archivos de paquete:

    • entry1.bundle.js que contiene el código completo de entry1.js , un requisito para jquery y no contiene el tiempo de ejecución
    • entry2.bundle.js que contiene el código completo de entry2.js , un requisito para jquery y no contiene el tiempo de ejecución
    • vendors.bundle.js que contiene el código completo de jquery y some_jquery_plugin y no contiene el tiempo de ejecución
    • manifest.bundle.js que contiene requisitos para cada otro paquete 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 paquete manifest . Este es el caso ideal.

Lo que no entiendo / No estoy seguro de entender

  • En el CASO 2, ¿por qué terminamos con el paquete de vendors contiene tanto el código común ( jquery ) como lo que quedó de la entrada de vendors ( some_jquery_plugin )? Según tengo entendido, lo que hizo CommonsChunkPlugin aquí fue que recopiló el código común ( jquery ), y como lo CommonsChunkPlugin al paquete de vendors , de alguna manera "fusionó" el código común en el paquete de vendors (que ahora solo contenía el código de some_jquery_plugin ). Por favor confirme o explique.

  • En el CASO 3 , no entiendo lo que sucedió cuando pasamos { names : [''vendors'', ''manifest''] } al complemento. Por qué / cómo se mantuvo intacto el paquete de vendors , que contenía tanto jquery como some_jquery_plugin , cuando jquery es claramente una dependencia común, y por qué el archivo manifest.bundle.js generado se creó de la manera en que se creó (requiriendo todos los demás paquetes y conteniendo el tiempo de ejecución )?


Así es como funciona el CommonsChunkPlugin .

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 .

CommonsChunkPlugin se ejecuta durante la fase de optimización de Webpack, lo que significa que funciona 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:

  1. Hay 3 fragmentos de entry ( entry1 , entry2 y vendors ).
  2. La configuración establece el fragmento de commons como un fragmento común.
  3. El complemento procesa el fragmento común común (dado que el fragmento no existe, se crea):
    1. Recopila los módulos que se usan más de una vez en los otros fragmentos: entry1 , entry2 y los vendors usan jquery por lo que el módulo se elimina de estos fragmentos y se agrega al fragmento commons .
    2. El fragmento de commons se marca como un fragmento de entry mientras que los fragmentos de entry1 , entry2 y vendors están sin marcar como entry .
  4. Finalmente, dado que el fragmento commons es un fragmento de entry , contiene el tiempo de ejecución y el módulo jquery .

CASO 2:

  1. Hay 3 fragmentos de entry ( entry1 , entry2 y vendors ).
  2. La configuración establece el fragmento de vendors como un fragmento común.
  3. El complemento procesa la porción común de los vendors :
    1. Recopila los módulos que se usan más de una vez en los otros fragmentos: entry1 y entry2 usan jquery para que el módulo se elimine de estos fragmentos (tenga en cuenta que no se agrega al fragmento de vendors porque el fragmento de vendors ya lo contiene).
    2. El fragmento de vendors se marca como un fragmento de entry mientras que los fragmentos de entry1 y entry2 se identifican como entry .
  4. Finalmente, dado que el fragmento de vendors es un fragmento de entry , contiene el tiempo de ejecución y los módulos jquery / jquery_plugin .

CASO 3:

  1. Hay 3 fragmentos de entry ( entry1 , entry2 y vendors ).
  2. La configuración establece el fragmento de vendors y el fragmento de manifest como fragmentos comunes.
  3. El complemento crea el fragmento de manifest ya que no existe.
  4. El complemento procesa la porción común de los vendors :
    1. Recopila los módulos que se usan más de una vez en los otros fragmentos: entry1 y entry2 usan jquery para que el módulo se elimine de estos fragmentos (tenga en cuenta que no se agrega al fragmento de vendors porque el fragmento de vendors ya lo contiene).
    2. El fragmento de vendors se marca como un fragmento de entry mientras que los fragmentos de entry1 y entry2 se identifican como entry .
  5. El complemento procesa el fragmento común manifest (dado que el fragmento no existe, se crea):
    1. Recopila los módulos que se usan más de una vez en los otros fragmentos: como no hay módulos usados ​​más de una vez, no se mueve ningún módulo.
    2. El fragmento de manifest se marca como fragmento de entry mientras que la entry1 , la entry2 y los vendors están sin marcar como entry .
  6. Finalmente, dado que el fragmento de manifest es un fragmento de entry , contiene el tiempo de ejecución.

Espero eso ayude.