有人可以解释Webpack的CommonsChunkPlugin
我得到了CommonsChunkPlugin查看所有入口点的一般要点,检查它们之间是否有常见的包/依赖关系,并将它们分离到它们自己的包中。
所以,我们假设我有以下configuration:
... 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其中包含来自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,但运行时现在被包含在
vendors捆绑包中。 这比以前的情况稍差,因为运行时现在在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包含每个其他包的需求并包含运行时
通过这种方式,我们最终得到了一些更小的包,运行时包含在
manifest包中。 这是理想的情况。 -
我不明白/我不知道我明白
-
在案例2中,为什么我们最终得到了包含公共代码(
jquery)和vendors条目(some_jquery_plugin)中剩余的任何一个的捆绑包? 根据我的理解,CommonsChunkPlugin在这里所做的是收集了通用代码(jquery),并且由于我们强制它将其输出到vendors捆绑包,所以它将通用代码“合并”到vendors捆绑包中包含来自some_jquery_plugin的代码)。 请确认或解释。 -
在案例3中,我不明白当我们将
{ names : ['vendors', 'manifest'] }传递给插件时发生了什么。 为什么/如何vendors捆绑保持不变,包含jquery和some_jquery_plugin,当jquery显然是一个共同的依赖,为什么生成的manifest.bundle.js文件创build它的方式创build(需要所有其他包并包含运行时)?
这就是CommonsChunkPlugin工作原理。
一个普通的块“接收”几个入口块共享的模块。 在Webpack存储库中可以find一个复杂configuration的好例子。
CommonsChunkPlugin在CommonsChunkPlugin的优化阶段运行,这意味着它在内存中运行,就在块被密封并写入磁盘之前。
当定义几个常用块时,它们按顺序处理。 在你的情况3,就像运行插件两次。 但是请注意, CommonsChunkPlugin可以有一个更复杂的configuration(minSize,minChunk等),影响模块移动的方式。
情况1:
- 有3个
entry块(entry,entry2和vendors)。 - 该configuration将公用块设置为公共块。
- 这个插件处理公共块(因为块不存在,它被创build):
- 它收集在其他块中
entry2使用的模块:entry1,entry2和entry2使用jquery以便将模块从这些块中移除并添加到commons块中。 -
entry2块被标记为entry块,而entry,entry2和vendors块被作为entry取消。
- 它收集在其他块中
- 最后,由于
commonschunk是一个entry块,它包含运行时和jquery模块。
情况2:
- 有3个
entry块(entry,entry2和vendors)。 - configuration将
vendors块设置为公共块。 - 该插件处理
vendors常见块:- 它收集在其他块中
entry2使用的模块:entry1和entry2使用jquery以便从这些块中删除模块(注意,由于vendors块已经包含它,因此不会将其添加到vendorsvendors块)。 -
vendors块被标记为entry块,而entry1和entry2块被作为entry取消标记。
- 它收集在其他块中
- 最后,由于
vendors块是一个entry块,它包含运行时和jquery/jquery_plugin模块。
案例3:
- 有3个
entry块(entry,entry2和vendors)。 - configuration将
vendors块和manifest块设置为常用块。 - 该插件创build
manifest块,因为它不存在。 - 该插件处理
vendors常见块:- 它收集在其他块中
entry2使用的模块:entry1和entry2使用jquery以便从这些块中删除模块(注意,由于vendors块已经包含它,因此不会将其添加到vendorsvendors块)。 -
vendors块被标记为entry块,而entry1和entry2块被作为entry取消标记。
- 它收集在其他块中
- 该插件处理
manifest公共块(因为块不存在,它被创build):- 它收集在其他块中多次使用的模块:由于没有多次使用模块,所以没有模块被移动。
-
manifest块被标记为entry块,而entry,entry2和vendors被标记为entry。
- 最后,由于
manifest块是一个entry块,它包含运行时。
希望能帮助到你。