誰かがWebpackのCommonsChunkPluginを説明できますか


82

CommonsChunkPluginは、すべてのエントリポイントを調べ、それらの間に共通のパッケージ/依存関係があるかどうかを確認し、それらを独自のバンドルに分離するという一般的な要点を理解しています。

したがって、次の構成があると仮定します。

...
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'
}
...

使用せずにバンドルした場合 CommonsChunkPlugin

最終的に3つの新しいバンドルファイルが作成されます。

  • entry1.bundle.jsそこから完全なコードが含まれているentry1.jsjqueryし、独自のランタイムが含まれています
  • entry2.bundle.jsそこから完全なコードが含まれているentry2.jsjqueryし、独自のランタイムが含まれています
  • vendors.bundle.jsそこから完全なコードが含まれているjquerysome_jquery_pluginし、独自のランタイムが含まれています

これは明らかに悪いことjqueryです。ページに3回読み込まれる可能性があるため、これは望ましくありません。

を使用してバンドルする場合 CommonsChunkPlugin

CommonsChunkPlugin次のいずれかに渡す引数に応じて、次のいずれかになります。

  • ケース1:合格{ name : 'commons' }すると、次のバンドルファイルが作成されます。

    • entry1.bundle.jsそこから完全なコードが含まentry1.jsための要件を、jqueryおよびランタイムが含まれていません
    • entry2.bundle.jsそこから完全なコードが含まentry2.jsための要件を、jqueryおよびランタイムが含まれていません
    • vendors.bundle.jsそこから完全なコードが含まsome_jquery_pluginための要件を、jqueryおよびランタイムが含まれていません
    • commons.bundle.jsからの完全なコードjqueryとランタイムが含まれています

    このようにして、全体的にいくつかの小さなバンドルになり、ランタイムはcommonsバンドルに含まれます。かなり大丈夫ですが、理想的ではありません。

  • ケース2:合格{ name : 'vendors' }すると、次のバンドルファイルが作成されます。

    • entry1.bundle.jsそこから完全なコードが含まentry1.jsための要件を、jqueryおよびランタイムが含まれていません
    • entry2.bundle.jsそこから完全なコードが含まentry2.jsための要件を、jqueryおよびランタイムが含まれていません
    • vendors.bundle.jsこれには、jqueryおよびからの完全なコードsome_jquery_pluginが含まれ、ランタイムが含まれます。

    このようにして、全体的にいくつかの小さなバンドルになりますが、ランタイムはvendorsバンドルに含まれるようになりました。ランタイムがvendorsバンドルに含まれているため、前のケースよりも少し悪化しています。

  • ケース3:合格{ names : ['vendors', 'manifest'] }すると、次のバンドルファイルが作成されます。

    • entry1.bundle.jsそこから完全なコードが含まentry1.jsための要件を、jqueryおよびランタイムが含まれていません
    • entry2.bundle.jsそこから完全なコードが含まentry2.jsための要件を、jqueryおよびランタイムが含まれていません
    • vendors.bundle.jsそこから完全なコードが含まれているjquerysome_jquery_pluginし、ランタイムが含まれていません
    • manifest.bundle.js これには、他のすべてのバンドルの要件とランタイムが含まれています

    このようにして、全体的にいくつかの小さなバンドルになり、ランタイムはmanifestバンドルに含まれます。これは理想的なケースです。

わからないこと/わからない

  • ではCASE 2なぜ私たちは、で終わるんでしたvendors(一般的なコードの両方を含むバンドルjquery)とから残ったものは何でもvendors(エントリーsome_jquery_plugin)?私の理解では、CommonsChunkPluginここで行ったことは、共通コード(jquery)を収集し、それをvendorsバンドルに出力するように強制したため、共通コードをvendorsバンドルに「マージ」したことです(現在は、からのコードのみが含まれています)。some_jquery_plugin)。確認または説明してください。

  • ではCASE 3私たちは渡されたときに何が起こったのか理解していない{ names : ['vendors', 'manifest'] }プラグインに。なぜ/どのようにされたvendorsバンドルは両方を含む、そのまま保持jquerysome_jquery_pluginするとき、jquery明らかに一般的な依存関係で、なぜ生成されたmanifest.bundle.jsファイルは、それが作成された方法を作成し(他のすべてのバンドルを必要とランタイムを含みますか)?


ケース1の場合、minChunksプロパティを指定する必要があると思います。
マルコ

10
私はあなたの質問からたくさんのことを学びました、どうもありがとう!
Rafael Eyng 2017年

1
❤これを尋ねると、このプラグインにすべてのこの時間を私の混乱をクリアするためにありがとうございました
グレン・ムハンマド・

たぶん誰かが知っているでしょう、これらの例はWebpack 4でどのように見えるでしょうか?
StalkAlex 2018年

回答:


105

これがどのようにCommonsChunkPlugin機能するかです。

共通チャンクは、複数のエントリチャンクによって共有されるモジュールを「受信」します。複雑な構成の良い例は、Webpackリポジトリにあります

CommonsChunkPluginチャンクが密封され、ディスクに書き込まれる直前に、それはメモリで動作する手段のWebPACKの最適化フェーズ中に実行されます。

複数の共通チャンクが定義されている場合、それらは順番に処理されます。あなたのケース3では、プラグインを2回実行するようなものです。ただしCommonsChunkPlugin、モジュールの移動方法に影響を与える、より複雑な構成(minSize、minChunksなど)を持つことができることに注意してください。

ケース1:

  1. 3つのがあるentryチャンク(entry1entry2およびvendors)が。
  2. 構成により、commonsチャンクが共通チャンクとして設定されます。
  3. プラグインはcommons共通チャンクを処理します(チャンクが存在しないため、作成されます)。
    1. これは他のチャンクに複数回使用されるモジュールを収集:entry1entry2及びvendors使用jqueryモジュールので、これらのチャンクから除去され、に追加されcommons、チャンク。
    2. commonsチャンクは、次のようにフラグが設定されentryている間、チャンクentry1entry2及びvendorsチャンクは以下のようにUNFLAGGEDれますentry
  4. 最後に、commonsチャンクはentryチャンクであるため、ランタイムとjqueryモジュールが含まれています。

ケース2:

  1. 3つのがあるentryチャンク(entry1entry2およびvendors)が。
  2. 構成により、vendorsチャンクが共通チャンクとして設定されます。
  3. プラグインはvendors共通のチャンクを処理します。
    1. :それは他のチャンクに複数回使用されているモジュールを収集entry1し、entry2使用することをjqueryモジュールがこれらのチャンク(これが追加されていないことに注意してくださいから削除されるようにvendorsするので、チャンクvendorsチャンクはすでにそれを含みます)。
    2. vendorsチャンクは、次のようにフラグが設定されentryている間チャンクentry1entry2チャンクは以下のようにUNFLAGGEDれますentry
  4. 最後に、vendorsチャンクはentryチャンクであるため、ランタイムとjquery/jquery_pluginモジュールが含まれています。

ケース3:

  1. 3つのがあるentryチャンク(entry1entry2およびvendors)が。
  2. 構成により、vendorsチャンクとmanifestチャンクが共通のチャンクとして設定されます。
  3. プラグインはmanifestチャンクが存在しないため、チャンクを作成します。
  4. プラグインはvendors共通のチャンクを処理します。
    1. :それは他のチャンクに複数回使用されているモジュールを収集entry1し、entry2使用することをjqueryモジュールがこれらのチャンク(これが追加されていないことに注意してくださいから削除されるようにvendorsするので、チャンクvendorsチャンクはすでにそれを含みます)。
    2. vendorsチャンクは、次のようにフラグが設定されentryている間チャンクentry1entry2チャンクは以下のようにUNFLAGGEDれますentry
  5. プラグインはmanifest共通チャンクを処理します(チャンクが存在しないため、作成されます)。
    1. 他のチャンクで複数回使用されているモジュールを収集します。複数回使用されているモジュールがないため、モジュールは移動されません。
    2. manifestチャンクは次のようにフラグが立てられているentry一方で、チャンクentry1entry2及びvendorsとしてUNFLAGGEDされていますentry
  6. 最後に、manifestチャンクはentryチャンクであるため、ランタイムが含まれています。

それが役に立てば幸い。


私が質問/明確にしたいいくつかのことを、あなたの答えにもこれらのポイントを追加してください:1)答えが1000%完全になるように、ケース1について同じステップバイステップの説明を行うことができますか?2)プラグインを実行{ names : ['vendors', 'manifest'] }して1回、2回、それを実行しているようである{ name : 'vendors' }としていったん{ name : 'manifest' }正しいですか、?3)「プラグインは共通のチャンクを処理する」と言うとき、それはbundle.jsファイル、メモリ、正しいに吐き出すコンテンツを作成することを意味しますか?4)「すべての一般的なチャンクを処理」するまで、ファイルに出力をまったく書き込まず、すべてメモリ内にあります
Dimitris Karagiannis 2016

2
あなたが答えたいと思うなら、私はもう一つ質問があります。レッツは、上から私の例で言う、entry1.jsそしてentry2.js、以外に、それらの間の別の一般的なファイルを持っていたjqueryファイル、のは、それを呼びましょうownLib.js。ケース2とケース3ではownLib.jsvendors.bundle.js正しい結果になりますか?ベンダーファイル以外の一般的なファイルが、チャンクとは別に独自のチャンクに分離されるようにするには、どうすればよいでしょうvendorsか。ご迷惑をおかけして申し訳ありませんが、私はまだwebpackの使い方を学んでいます
Dimitris Karagiannis

7
はい、そのownLib.js通りです。最初の一般的なチャンクに配置されます。別のチャンクで一般的な依存関係を収集する場合は、次のようなものを渡す必要があります{ names : ['common', 'vendors', 'manifest'] }
Laurent Etiemble 2016

6
素晴らしい質問、素晴らしい答え、素晴らしい議論。ようやく手に入れたようです。
oluckyman 2016年

3
私は最後のをCommonsChunkPluginのドキュメントを読んで過ごしましたが、これは実行後に処理されたチャンクが「エントリとしてフラグが立てられていない」ことを読んだ最初の場所です。それは基本的に私が問題を抱えていたすべてを説明します-私が複数回賛成することができれば、私はそうします。
コーダー2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.