web-dev-qa-db-ja.com

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

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.jsおよびjqueryからの完全なコードが含まれ、独自のランタイムが含まれます
  • entry2.bundle.jsにはentry2.jsおよびjqueryからの完全なコードが含まれ、独自のランタイムが含まれます
  • vendors.bundle.jsにはjqueryおよびsome_jquery_pluginからの完全なコードが含まれ、独自のランタイムが含まれます

jqueryをページに3回ロードする可能性があるため、これは明らかに悪いです。したがって、それは望ましくありません。

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

CommonsChunkPluginに渡す引数に応じて、次のいずれかが発生します。

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

    • entry1.bundle.jsは、jqueryの要件であるentry1.jsの完全なコードを含み、ランタイムは含まれません
    • entry2.bundle.jsは、jqueryの要件であるentry2.jsの完全なコードを含み、ランタイムは含まれません
    • vendors.bundle.jsは、jqueryの要件であるsome_jquery_pluginの完全なコードを含み、ランタイムは含まれません
    • commons.bundle.jsにはjqueryからの完全なコードが含まれ、ランタイムが含まれます

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

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

    • entry1.bundle.jsは、jqueryの要件であるentry1.jsの完全なコードを含み、ランタイムは含まれません
    • entry2.bundle.jsは、jqueryの要件であるentry2.jsの完全なコードを含み、ランタイムは含まれません
    • vendors.bundle.jsには、jqueryおよびsome_jquery_pluginの完全なコードが含まれ、ランタイムが含まれます。

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

  • ケース3:{ names : ['vendors', 'manifest'] }を渡すと、次のバンドルファイルになります。

    • entry1.bundle.jsは、jqueryの要件であるentry1.jsの完全なコードを含み、ランタイムは含まれません
    • entry2.bundle.jsは、jqueryの要件であるentry2.jsの完全なコードを含み、ランタイムは含まれません
    • jqueryおよびvendors.bundle.jsの完全なコードを含み、ランタイムを含まないsome_jquery_plugin
    • manifest.bundle.jsは、他のすべてのバンドルの要件を含み、ランタイムを含みます

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

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

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

  • ケースプラグインに{ names : ['vendors', 'manifest'] }を渡したときに何が起こったのかわかりません。 vendorsが明らかに一般的な依存関係であるときに、jquerysome_jquery_pluginの両方を含むjqueryバンドルがそのまま保持された理由/方法、および生成されたmanifest.bundle.jsファイルが作成された方法で作成されました(他のすべてのバンドルが必要で、ランタイムが含まれています)?

79

これがCommonsChunkPluginの仕組みです。

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

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

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

ケース1:

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

ケース2:

  1. 3つのentryチャンク(entry1entry2およびvendors)。
  2. この構成では、vendorsチャンクを共通のチャンクとして設定します。
  3. プラグインはvendors共通​​チャンクを処理します:
    1. 他のチャンクで複数回使用されているモジュールを収集します:entry1およびentry2jqueryを使用して、これらのチャンクからモジュールを削除します(vendorsチャンクにはすでに含まれているため、vendorsチャンクには追加されません)。
    2. vendorsチャンクにはentryチャンクとしてフラグが付けられ、entry1およびentry2チャンクはentryとしてフラグが解除されます。
  4. 最後に、vendorsチャンクはentryチャンクであるため、ランタイムとjquery/jquery_pluginモジュール。

ケース3:

  1. 3つのentryチャンク(entry1entry2およびvendors)。
  2. この構成では、vendorsチャンクとmanifestチャンクを共通のチャンクとして設定します。
  3. プラグインはmanifestチャンクが存在しないため作成します。
  4. プラグインはvendors共通​​チャンクを処理します:
    1. 他のチャンクで複数回使用されているモジュールを収集します:entry1およびentry2jqueryを使用して、これらのチャンクからモジュールを削除します(vendorsチャンクにはすでに含まれているため、vendorsチャンクには追加されません)。
    2. vendorsチャンクにはentryチャンクとしてフラグが付けられ、entry1およびentry2チャンクはentryとしてフラグが解除されます。
  5. プラグインはmanifest共通​​チャンクを処理します(チャンクが存在しないため、作成されます):
    1. 他のチャンクで複数回使用されるモジュールを収集します。複数回使用されるモジュールがないため、モジュールは移動されません。
    2. manifestチャンクにはentryチャンクとしてフラグが付けられますが、entry1entry2およびvendorsは、entryとしてフラグが解除されます。
  6. 最後に、manifestチャンクはentryチャンクであるため、ランタイムが含まれています。

それが役に立てば幸い。

103