首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >谁能解释一下Webpack的CommonsChunkPlugin

谁能解释一下Webpack的CommonsChunkPlugin
EN

Stack Overflow用户
提问于 2016-09-17 22:53:35
回答 1查看 9.9K关注 0票数 81

我得到的一般要点是,CommonsChunkPlugin查看所有入口点,检查它们之间是否有公共的包/依赖项,并将它们分离到自己的包中。

因此,让我们假设我有以下配置:

代码语言:javascript
复制
...
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的完整代码,并包含自己的runtime
  • entry2.bundle.js,其中包含来自entry2.jsjquery的完整代码,并包含自己的runtime
  • vendors.bundle.js,其中包含来自jquerysome_jquery_plugin的完整代码,并包含自己的运行时

这显然很糟糕,因为我可能会在页面中加载3次jquery,所以我们不希望发生这种情况。

如果我使用CommonsChunkPlugin捆绑

根据我传递给CommonsChunkPlugin的参数的不同,可能会发生以下情况:

  • CASE 1 :如果我传递{ name : 'commons' },我将得到以下包文件:

代码语言:javascript
复制
- `entry1.bundle.js` which contains the complete code from `entry1.js`, a requirement for `jquery` and does not contain the runtime
- `entry2.bundle.js` which contains the complete code from `entry2.js`, a requirement for `jquery` and does not contain the runtime
- `vendors.bundle.js` which contains the complete code from `some_jquery_plugin`, a requirement for `jquery` and does not contain the runtime
- `commons.bundle.js` which contains the complete code from `jquery` and contains the runtime

这样,我们最终得到了一些更小的包,运行时包含在commons包中。相当不错,但不是很理想。

  • CASE 2 :如果我传递{ name : 'vendors' },我将得到以下包文件:

代码语言:javascript
复制
- `entry1.bundle.js` which contains the complete code from `entry1.js`, a requirement for `jquery` and does not contain the runtime
- `entry2.bundle.js` which contains the complete code from `entry2.js`, a requirement for `jquery` and does not contain the runtime
- `vendors.bundle.js` which contains the complete code from `jquery` and `some_jquery_plugin` and contains the runtime. 

同样,通过这种方式,我们最终得到了一些更小的包,但运行时现在包含在vendors包中。这比前一种情况更糟糕,因为运行时现在位于vendors包中。

  • CASE 3 :如果我传递{ names : ['vendors', 'manifest'] },我将得到以下包文件:

代码语言:javascript
复制
- `entry1.bundle.js` which contains the complete code from `entry1.js`, a requirement for `jquery` and does not contain the runtime
- `entry2.bundle.js` which contains the complete code from `entry2.js`, a requirement for `jquery` and does not contain the runtime
- `vendors.bundle.js` which contains the complete code from `jquery` and `some_jquery_plugin` and does not contain the runtime
- `manifest.bundle.js` which contains requirements for every other bundle and contains the runtime

这样,我们最终得到了一些更小的包,运行时包含在manifest包中。这是最理想的情况。

我不明白的/我不确定我明白了

  • In CASE 2为什么我们最终会得到包含通用代码(jquery)和vendors条目(some_jquery_plugin)的vendors包?据我所知,CommonsChunkPlugin在这里所做的是收集公共代码(jquery),因为我们强制它将其输出到vendors包,所以它将公共代码“合并”到vendors包中(它现在只包含来自some_jquery_plugin的代码)。请确认或解释。
  • In CASE 3我不明白当我们将{ names : ['vendors', 'manifest'] }传递给插件时发生了什么。为什么/如何保持vendors包完好无损,同时包含jquerysome_jquery_plugin,而jquery显然是一个常见的依赖项,为什么生成的manifest.bundle.js文件按照创建的方式创建(需要所有其他包并包含运行时) ?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-09-21 01:58:44

这就是CommonsChunkPlugin的工作方式。

一个公共块“接收”由几个条目块共享的模块。复杂配置的一个很好的例子可以在Webpack repository中找到。

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

当定义了几个公共块时,将按顺序处理它们。在你的例子3中,它就像是运行了两次插件。但请注意,CommonsChunkPlugin可能具有更复杂的配置(minSize、minChunks等),这会影响模块的移动方式。

案例1:

  1. 有3个entry区块(entry1entry2vendors).
  2. The配置将commons区块设置为公共区块。
  3. 插件处理commons公共区块(由于该区块不存在,因此会创建它):<代码>G118<代码>H119它收集在其他区块中多次使用的模块:<代码>D20,entry2vendors使用jquery,因此模块将从这些区块中删除并添加到commons区块中。
  4. commons区块被标记为entry区块,而entry1、D30和D31区块则未被标记为so

  1. 最后,由于commons块是一个entry块,因此它包含运行时和jquery模块。

案例2:

  1. 有3个entry区块(entry1entry2vendors).
  2. The配置将vendors区块设置为公共区块。
  3. 插件处理vendors公共区块:
    1. 它收集在其他区块中多次使用的模块:entry1entry2使用D62,因此将从这些区块中删除模块(请注意,不会将其添加到D63区块中,因为D64区块已经包含它)。H265H166区块被标记为D68区块而未标记为entry.

entry1entry2区块

  1. 最后,由于vendors块是一个entry块,因此它包含运行时和jquery/jquery_plugin模块。

案例3:

  1. 有3个entry区块(entry1entry2vendors).
  2. The配置将vendors区块和manifest区块设置为公共区块。
  3. 插件创建manifest区块,因为它不存在。
  4. 插件处理vendors公共区块:<代码>G1102<代码>H1103它收集在其他区块中多次使用的模块:D104和D105使用D106,因此该模块将从这些区块中删除(请注意,不会将其添加到D107区块中,因为
  5. vendors区块被标记为entry区块,而entry1entry2区块未被标记为entry区块

  1. 插件处理manifest公共区块(由于该区块不存在,因此会创建它):
    1. 它收集在其他区块中多次使用的模块:由于没有超过一次使用的模块,因此不会移动任何模块。
    2. manifest区块标记为entry区块,而D129、D130和D131未标记为entry.

  1. 最后,由于manifest块是一个entry块,因此它包含运行时。

希望能有所帮助。

票数 106
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39548175

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档