有人可以解释Webpack的CommonsChunkPlugin

Dim*_*nis 79 javascript bundle webpack commonschunkplugin webpack-plugin

我得到了通用的要点,即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'
}
...
Run Code Online (Sandbox Code Playgroud)

如果我不使用捆绑 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其中包含完整的代码entry1.js,需要jquery和不包含运行时
    • entry2.bundle.js其中包含完整的代码entry2.js,需要jquery和不包含运行时
    • vendors.bundle.js其中包含完整的代码some_jquery_plugin,需要jquery和不包含运行时
    • commons.bundle.js其中包含完整的代码jquery并包含运行时

    这样我们最终会得到一些较小的bundle,运行时包含在commonsbundle中.相当不错但不理想.

  • 情况2:如果我通过,{ name : 'vendors' }我将得到以下捆绑文件:

    • entry1.bundle.js其中包含完整的代码entry1.js,需要jquery和不包含运行时
    • entry2.bundle.js其中包含完整的代码entry2.js,需要jquery和不包含运行时
    • vendors.bundle.js它包含来自jquery和的完整代码,some_jquery_plugin并包含运行时.

    这样,我们最终总体上会得到一些较小的bundle,但运行时现在包含在vendorsbundle中.它比前一种情况稍差,因为运行时现在在vendors捆绑中.

  • 案例3:如果我通过,{ names : ['vendors', 'manifest'] }我将最终得到以下捆绑文件:

    • entry1.bundle.js其中包含完整的代码entry1.js,需要jquery和不包含运行时
    • entry2.bundle.js其中包含完整的代码entry2.js,需要jquery和不包含运行时
    • vendors.bundle.js其中包含完整的代码jquery,some_jquery_plugin并且不包含运行时
    • manifest.bundle.js 其中包含每个其他bundle的需求并包含运行时

    这样我们最终会得到一些较小的bundle,运行时包含在manifestbundle中.这是理想的情况.

我不明白/我不确定我理解

  • 案例2中,为什么我们最终得到vendors包含公共代码(jquery)和vendors条目(some_jquery_plugin)中剩余的内容的包?根据我的理解,CommonsChunkPlugin这里做了什么,它收集了公共代码(jquery),并且因为我们强制它将它输出到vendorsbundle,它将公共代码"合并"到vendorsbundle中(现在只包含来自some_jquery_plugin).请确认或解释.

  • 案例3中,我不明白当我们传递{ names : ['vendors', 'manifest'] }给插件时发生了什么.为什么/是如何的vendors束保持完好,同时含有jquerysome_jquery_plugin,当jquery显然是一种常见的依赖,以及为什么生成的manifest.bundle.js文件来创建它的创建方式(要求所有其他包和含有运行时)?

Lau*_*ble 103

这是如何CommonsChunkPlugin工作的.

公共块"接收"由多个条目块共享的模块.可以在Webpack存储库中找到复杂配置的一个很好的示例.

CommonsChunkPlugin在Webpack的优化阶段运行,这意味着它在内存中运行,就在块被密封并写入磁盘之前.

当定义了几个公共块时,它们将按顺序处理.在你的情况3中,它就像运行插件两次.但是请注意,CommonsChunkPlugin可以使用更复杂的配置(minSize,minChunks等)来影响模块的移动方式.

情况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模块.

案例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_pluginmodules.

案例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,entry2并且vendors是未标记的entry.
  6. 最后,由于manifest块是一个entry块,它包含运行时.

希望能帮助到你.

  • 是的,这是正确的:`ownLib.js`将放在第一个共同的chunck中.如果你想在另一个chunck中收集常见的依赖关系,你必须传递这样的东西:`{names:['common','vendors','manifest']}`. (7认同)
  • 很棒的问题,很棒的答案,很棒的讨论.好像我终于明白了. (6认同)
  • 我花了最后一天**阅读CommonsChunkPlugin文档,这是我读过的第一个地方,执行后,处理后的块"没有标记为条目".这基本上解释了我遇到麻烦的一切 - 如果我能不止一次地投票,我会的. (3认同)
  • 如果你想回答,我还有一个问题.让我们说在上面的示例中,`entry1.js`和`entry2.js`之间有另一个公共文件,除了`jquery`文件之外,我们称之为`ownLib.js`.在案例2和案例3中,`ownLib.js`最终会出现在"vendors.bundle.js"中吗?除了"供应商"块之外,你们如何才能将除供应商文件以外的常见文件分成他们自己的块?很抱歉打扰你,但我还在学习如何使用webpack (2认同)