有人可以解释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,运行时被包含在
commons
bundle中。 很好,但不理想。 -
-
情况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
取消。
- 它收集在其他块中
- 最后,由于
commons
chunk是一个entry
块,它包含运行时和jquery
模块。
情况2:
- 有3个
entry
块(entry
,entry2
和vendors
)。 - configuration将
vendors
块设置为公共块。 - 该插件处理
vendors
常见块:- 它收集在其他块中
entry2
使用的模块:entry1
和entry2
使用jquery
以便从这些块中删除模块(注意,由于vendors
块已经包含它,因此不会将其添加到vendors
vendors
块)。 -
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
块已经包含它,因此不会将其添加到vendors
vendors
块)。 -
vendors
块被标记为entry
块,而entry1
和entry2
块被作为entry
取消标记。
- 它收集在其他块中
- 该插件处理
manifest
公共块(因为块不存在,它被创build):- 它收集在其他块中多次使用的模块:由于没有多次使用模块,所以没有模块被移动。
-
manifest
块被标记为entry
块,而entry
,entry2
和vendors
被标记为entry
。
- 最后,由于
manifest
块是一个entry
块,它包含运行时。
希望能帮助到你。