Quelqu’un peut-il expliquer les CommonsChunkPlugin de Webpack

Je comprends l’essentiel que le CommonsChunkPlugin examine tous les points d’entrée, vérifie s’il y a des paquets / dépendances communs entre eux et les sépare dans leur propre paquet.

Donc, supposons que j’ai la configuration suivante:

 ... 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 je regroupe sans utiliser CommonsChunkPlugin

Je vais me retrouver avec 3 nouveaux fichiers bundle:

  • entry1.bundle.js qui contient le code complet de entry1.js et jquery et contient son propre runtime
  • entry2.bundle.js qui contient le code complet de entry2.js et jquery et contient son propre runtime
  • vendors.bundle.js qui contient le code complet de jquery et some_jquery_plugin et contient son propre runtime

C’est évidemment mauvais parce que je vais potentiellement charger 3 fois jquery dans la page, donc nous ne voulons pas cela.

Si je combine avec CommonsChunkPlugin

Selon les arguments que je transmets à CommonsChunkPlugin les CommonsChunkPlugin suivantes se produiront:

  • CAS 1: Si je passe { name : 'commons' } je vais me retrouver avec les fichiers suivants:

    • entry1.bundle.js qui contient le code complet de entry1.js , une exigence pour jquery et ne contient pas le runtime
    • entry2.bundle.js qui contient le code complet de entry2.js , une exigence pour jquery et ne contient pas le runtime
    • vendors.bundle.js qui contient le code complet de some_jquery_plugin , une condition requirejse pour jquery et ne contient pas le runtime
    • commons.bundle.js qui contient le code complet de jquery et contient le runtime

    De cette façon, nous obtenons des paquets plus petits et le runtime est contenu dans le paquet commons . Assez ok mais pas idéal.

  • CAS 2: Si je passe { name : 'vendors' } je me retrouverai avec les fichiers suivants:

    • entry1.bundle.js qui contient le code complet de entry1.js , une exigence pour jquery et ne contient pas le runtime
    • entry2.bundle.js qui contient le code complet de entry2.js , une exigence pour jquery et ne contient pas le runtime
    • vendors.bundle.js qui contient le code complet de jquery et some_jquery_plugin et contient le runtime.

    De cette façon, encore une fois, nous nous retrouvons avec des paquets plus petits dans l’ensemble, mais le runtime est maintenant contenu dans l’offre groupée. C’est un peu pire que le cas précédent, car le runtime est maintenant dans le lot des vendors .

  • CAS 3: Si je passe { names : ['vendors', 'manifest'] } je vais me retrouver avec les fichiers suivants:

    • entry1.bundle.js qui contient le code complet de entry1.js , une exigence pour jquery et ne contient pas le runtime
    • entry2.bundle.js qui contient le code complet de entry2.js , une exigence pour jquery et ne contient pas le runtime
    • vendors.bundle.js qui contient le code complet de jquery et some_jquery_plugin et ne contient pas le runtime
    • manifest.bundle.js qui contient les exigences pour tous les autres bundles et contient le runtime

    De cette façon, nous obtenons des paquets plus petits et le runtime est contenu dans le paquet manifest . C’est le cas idéal.

Ce que je ne comprends pas / Je ne suis pas sûr de comprendre

  • Dans CAS 2, pourquoi nous sums-nous retrouvés avec le lot de vendors contenant à la fois le code commun ( jquery ) et tout ce qui restait de l’entrée du vendors ( some_jquery_plugin )? D’après ce que j’ai compris, le CommonsChunkPlugin fait en sorte de rassembler le code commun ( jquery ), et comme nous l’avons forcé à le publier dans le groupe de vendors , il a en quelque sorte “fusionné” le code commun contenait le code de some_jquery_plugin ). Veuillez confirmer ou expliquer.

  • Dans CAS 3, je ne comprends pas ce qui s’est passé lorsque nous avons passé { names : ['vendors', 'manifest'] } au plug-in. Pourquoi / comment les some_jquery_plugin des vendors conservées, contenant à la fois jquery et some_jquery_plugin , lorsque jquery est clairement une dépendance commune et pourquoi le fichier manifest.bundle.js généré a été créé de la manière )?

Voilà comment fonctionne le CommonsChunkPlugin .

Un bloc commun “reçoit” les modules partagés par plusieurs blocs d’entrée. Un bon exemple de configuration complexe peut être trouvé dans le référentiel Webpack .

Le CommonsChunkPlugin est exécuté pendant la phase d’optimisation de Webpack, ce qui signifie qu’il fonctionne en mémoire, juste avant que les blocs ne soient scellés et écrits sur le disque.

Lorsque plusieurs blocs communs sont définis, ils sont traités dans l’ordre. Dans votre cas 3, c’est comme exécuter le plugin deux fois. Mais veuillez noter que le CommonsChunkPlugin peut avoir une configuration plus complexe (minSize, minChunks, etc.) qui affecte la façon dont les modules sont déplacés.

CAS 1:

  1. Il y a 3 morceaux d’ entry ( entry2 , entry2 et vendors ).
  2. La configuration définit le morceau commons comme un bloc commun.
  3. Le plugin traite le bloc commun des commons (puisque le bloc n’existe pas, il est créé):
    1. Il collecte les modules qui sont utilisés plus d’une fois dans les autres blocs: entry2 , entry2 et les vendors utilisent jquery pour que le module soit supprimé de ces blocs et qu’il soit ajouté au bloc des ressources commons .
    2. Le fragment commons est marqué comme un bloc d’ entry alors que les blocs entry2 , entry2 et vendors sont pas identifiés comme entry .
  4. Enfin, le fragment commons étant un bloc d’ entry il contient le module runtime et le module jquery .

CAS 2:

  1. Il y a 3 morceaux d’ entry ( entry2 , entry2 et vendors ).
  2. La configuration définit le bloc du vendors comme un bloc commun.
  3. Le plugin traite le bloc commun des vendors :
    1. Il collecte les modules utilisés plus d’une fois dans les autres blocs: entry2 et entry2 utilisent jquery pour que le module soit supprimé de ces blocs (notez qu’il n’est pas ajouté au bloc du vendors car le bloc du vendors contient déjà).
    2. Le bloc des vendors est marqué comme un bloc d’ entry alors que les blocs entry2 et entry2 sont pas identifiés comme entry .
  4. Enfin, le bloc vendors étant un bloc d’ entry , il contient les modules runtime et jquery / jquery_plugin .

CAS 3:

  1. Il y a 3 morceaux d’ entry ( entry2 , entry2 et vendors ).
  2. La configuration définit le bloc du vendors et le bloc manifest sous forme de blocs communs.
  3. Le plugin crée le fragment manifest car il n’existe pas.
  4. Le plugin traite le bloc commun des vendors :
    1. Il collecte les modules utilisés plus d’une fois dans les autres blocs: entry2 et entry2 utilisent jquery pour que le module soit supprimé de ces blocs (notez qu’il n’est pas ajouté au bloc du vendors car le bloc du vendors contient déjà).
    2. Le bloc des vendors est marqué comme un bloc d’ entry alors que les blocs entry2 et entry2 sont pas identifiés comme entry .
  5. Le plugin traite le chunk commun manifest (puisque le chunk n’existe pas, il est créé):
    1. Il collecte les modules utilisés plus d’une fois dans les autres blocs: comme aucun module n’est utilisé plus d’une fois, aucun module n’est déplacé.
    2. Le bloc manifest est marqué comme bloc d’ entry alors que l’ entry1 , l’ entry2 et les vendors sont pas identifiés comme entry .
  6. Enfin, puisque le bloc manifest est un bloc d’ entry il contient le runtime.

J’espère que cela aide.