我得到了一个基本要点,即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
which contains the complete code fromentry1.js
, a requirement forjquery
and does not contain the runtimeentry2.bundle.js
which contains the complete code fromentry2.js
, a requirement forjquery
and does not contain the runtimevendors.bundle.js
which contains the complete code fromsome_jquery_plugin
, a requirement forjquery
and does not contain the runtimecommons.bundle.js
which contains the complete code fromjquery
and contains the runtime
This way we end up with some smaller bundles overall and the runtime is contained in the
commons
bundle. Pretty ok but not ideal.CASE 2 : If I pass
{ name : 'vendors' }
I will end up with the following bundle files:entry1.bundle.js
which contains the complete code fromentry1.js
, a requirement forjquery
and does not contain the runtimeentry2.bundle.js
which contains the complete code fromentry2.js
, a requirement forjquery
and does not contain the runtimevendors.bundle.js
which contains the complete code fromjquery
andsome_jquery_plugin
and contains the runtime.
This way, again, we end up with some smaller bundles overall but the runtime is now contained in the
vendors
bundle. It's a little worse than the previous case, since the runtime is now in thevendors
bundle.CASE 3 : If I pass
{ names : ['vendors', 'manifest'] }
I will end up with the following bundle files:entry1.bundle.js
which contains the complete code fromentry1.js
, a requirement forjquery
and does not contain the runtimeentry2.bundle.js
which contains the complete code fromentry2.js
, a requirement forjquery
and does not contain the runtimevendors.bundle.js
which contains the complete code fromjquery
andsome_jquery_plugin
and does not contain the runtimemanifest.bundle.js
which contains requirements for every other bundle and contains the runtime
This way we end up with some smaller bundles overall and the runtime is contained in the
manifest
bundle. This is the ideal case.
What I do not understand/I am not sure I understand
In CASE 2 why did we end up with the
vendors
bundle containing both the common code (jquery
) and whatever remained from thevendors
entry (some_jquery_plugin
)? From my understanding, what theCommonsChunkPlugin
did here was that it gathered the common code (jquery
), and since we forced it to output it to thevendors
bundle, it kind of "merged" the common code into thevendors
bundle (which now only contained the code fromsome_jquery_plugin
). Please confirm or explain.In CASE 3 I do not understand what happened when we passed
{ names : ['vendors', 'manifest'] }
to the plugin. Why/how was thevendors
bundle kept intact, containing bothjquery
andsome_jquery_plugin
, whenjquery
is clearly a common dependency, and why was the generatedmanifest.bundle.js
file created the way it was created (requiring all other bundles and containing the runtime) ?
这就是
CommonsChunkPlugin
工作原理。一个公共块“接收”由几个入口块共享的模块。在Webpack存储库中可以找到复杂配置的一个很好的例子。
它
CommonsChunkPlugin
在Webpack的优化阶段运行,这意味着它在内存被密封并写入磁盘之前就在内存中运行。当定义了几个通用块时,将按顺序对其进行处理。在您的情况3中,就像两次运行插件一样。但是请注意,它们
CommonsChunkPlugin
可能具有更复杂的配置(minSize,minChunks等),这会影响模块的移动方式。情况1:
entry
块(entry1
,entry2
和vendors
)。commons
块设置为公共块。commons
公共块(由于该块不存在,因此将创建它):entry1
,entry2
并vendors
使用,jquery
以便从这些块中删除该模块并将其添加到该commons
块中。commons
块被标记为entry
,而该块entry1
,entry2
并且vendors
块被作为未标记entry
。commons
块是entry
块,因此它包含运行时和jquery
模块。情况2:
entry
块(entry1
,entry2
和vendors
)。vendors
块设置为公共块。vendors
公共块:entry1
并entry2
使用,jquery
以便从这些块中删除该模块(请注意,vendors
由于该vendors
块已包含该模块,因此未将其添加到该块中)。vendors
块被标记为entry
,而该块entry1
和entry2
块旗标被作为entry
。vendors
块是entry
块,因此它包含运行时和jquery
/jquery_plugin
模块。情况3:
entry
块(entry1
,entry2
和vendors
)。vendors
块和manifest
块设置为公共块。manifest
块,因为它不存在。vendors
公共块:entry1
andentry2
usejquery
so the module is removed from these chunks (note that it is not added to thevendors
chunk because thevendors
chunk already contains it).vendors
chunk is flagged as anentry
chunk while theentry1
andentry2
chunks are unflagged asentry
.manifest
common chunk (since the chunk does not exist, it is created):manifest
chunk is flagged asentry
chunk while theentry1
,entry2
andvendors
are unflagged asentry
.manifest
chunk is anentry
chunk it contains the runtime.Hope it helps.