1. ホーム
  2. javascript

[解決済み] Webpack の CommonsChunkPlugin について教えてください。

2023-08-13 05:32:23

質問

一般的な話として 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 に渡す引数によって、次のようなことが起こります。

  • CASE 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 バンドルに含まれています。かなり良いですが、理想的ではありません。

  • CASE 2 : もし私が { name : 'vendors' } を渡すと、以下のようなバンドルファイルができあがります。

    • entry1.bundle.js からの完全なコードを含む entry1.js の要件である jquery を含んでおらず、ランタイムの
    • entry2.bundle.js から完全なコードを含んでいます。 entry2.js の要件である jquery を含んでおらず、ランタイムの
    • vendors.bundle.js から完全なコードを含んでいます。 jquerysome_jquery_plugin であり、ランタイムを含んでいます。

    この方法でも、全体としては小さなバンドルになりますが、ランタイムが vendors バンドルに含まれています。前のケースより少し悪いのは、ランタイムが vendors バンドルになったからです。

  • CASE 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 バンドルに出力するよう強制したので、それは一種の "merged" 共通コードを vendors バンドルにマージしています。 some_jquery_plugin ). 確認または説明をお願いします。

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

どのように解決するのですか?

このように CommonsChunkPlugin は動作します。

共通のチャンクはいくつかのエントリーチャンクで共有されるモジュールを "受け取ります" 。 複雑な構成の良い例としては Webpack リポジトリ .

CommonsChunkPlugin は Webpack の最適化フェーズで実行されます。つまり、チャンクがシールされてディスクに書き込まれる直前に、メモリ上で動作します。

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

CASE 1:

  1. 3つあります。 entry チャンク ( entry1 , entry2vendors ).
  2. コンフィギュレーションでは commons チャンクを共通のチャンクとして設定します。
  3. プラグインは commons の共通チャンクを処理します(チャンクが存在しないため、作成されます)。
    1. 他のチャンクで複数回使用されているモジュールを集めます。 entry1 , entry2vendors を使う jquery であるため、これらのチャンクからモジュールが削除され、モジュールが commons チャンクに追加されます。
    2. commons チャンクのフラグは entry チャンクとしてフラグが立ちますが entry1 , entry2vendors というチャンクは、フラグを立てずに entry .
  4. 最後に commons チャンクは entry チャンクにはランタイムと jquery モジュールが含まれています。

CASE 2:

  1. 3つあります。 entry チャンク ( entry1 , entry2vendors ).
  2. コンフィギュレーションでは vendors チャンクを共通のチャンクとして設定します。
  3. プラグインは vendors 共通チャンクを処理します。
    1. 他のチャンクで複数回使用されているモジュールを集めます。 entry1entry2 を使う jquery であるため、これらのチャンクからモジュールが削除されます(モジュールが vendors チャンクに追加されないことに注意してください。 vendors チャンクはすでにそれを含んでいるからです)。
    2. vendors チャンクのフラグは entry チャンクとしてフラグが立ちますが entry1entry2 というチャンクは、フラグを立てずに entry .
  4. 最後に vendors チャンクは entry チャンクには、ランタイムと jquery / jquery_plugin モジュールを使用します。

CASE 3:

  1. 3つあります。 entry チャンク ( entry1 , entry2vendors ).
  2. コンフィギュレーションでは vendors チャンクと manifest チャンクを共通のチャンクとする。
  3. プラグインが作成する manifest チャンクが存在しないので作成します。
  4. プラグインは vendors 共通チャンクを処理します。
    1. 他のチャンクで複数回使用されているモジュールを集めます。 entry1entry2 を使う jquery であるため、これらのチャンクからモジュールが削除されます(モジュールが vendors チャンクに追加されないことに注意してください。 vendors チャンクはすでにそれを含んでいるからです)。
    2. vendors チャンクのフラグは entry チャンクとしてフラグが立ちますが entry1entry2 というチャンクは、フラグを立てずに entry .
  5. このプラグインは manifest の共通チャンクを処理します(チャンクが存在しないため、作成されます)。
    1. 他のチャンクで複数回使用されているモジュールを収集します。複数回使用されているモジュールがないため、どのモジュールも移動されません。
    2. manifest というフラグが立てられます。 entry チャンクであるのに対し entry1 , entry2vendors はフラグが立っていないため entry .
  6. 最後に manifest チャンクは entry チャンクであり、ランタイムを含んでいます。

お役に立てれば幸いです。