我得到了一个基本要点,即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.jswhich contains the complete code fromentry1.js, a requirement forjqueryand does not contain the runtimeentry2.bundle.jswhich contains the complete code fromentry2.js, a requirement forjqueryand does not contain the runtimevendors.bundle.jswhich contains the complete code fromsome_jquery_plugin, a requirement forjqueryand does not contain the runtimecommons.bundle.jswhich contains the complete code fromjqueryand contains the runtime
This way we end up with some smaller bundles overall and the runtime is contained in the
commonsbundle. Pretty ok but not ideal.CASE 2 : If I pass
{ name : 'vendors' }I will end up with the following bundle files:entry1.bundle.jswhich contains the complete code fromentry1.js, a requirement forjqueryand does not contain the runtimeentry2.bundle.jswhich contains the complete code fromentry2.js, a requirement forjqueryand does not contain the runtimevendors.bundle.jswhich contains the complete code fromjqueryandsome_jquery_pluginand contains the runtime.
This way, again, we end up with some smaller bundles overall but the runtime is now contained in the
vendorsbundle. It's a little worse than the previous case, since the runtime is now in thevendorsbundle.CASE 3 : If I pass
{ names : ['vendors', 'manifest'] }I will end up with the following bundle files:entry1.bundle.jswhich contains the complete code fromentry1.js, a requirement forjqueryand does not contain the runtimeentry2.bundle.jswhich contains the complete code fromentry2.js, a requirement forjqueryand does not contain the runtimevendors.bundle.jswhich contains the complete code fromjqueryandsome_jquery_pluginand does not contain the runtimemanifest.bundle.jswhich 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
manifestbundle. 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
vendorsbundle containing both the common code (jquery) and whatever remained from thevendorsentry (some_jquery_plugin)? From my understanding, what theCommonsChunkPlugindid here was that it gathered the common code (jquery), and since we forced it to output it to thevendorsbundle, it kind of "merged" the common code into thevendorsbundle (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 thevendorsbundle kept intact, containing bothjqueryandsome_jquery_plugin, whenjqueryis clearly a common dependency, and why was the generatedmanifest.bundle.jsfile 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公共块:entry1andentry2usejqueryso the module is removed from these chunks (note that it is not added to thevendorschunk because thevendorschunk already contains it).vendorschunk is flagged as anentrychunk while theentry1andentry2chunks are unflagged asentry.manifestcommon chunk (since the chunk does not exist, it is created):manifestchunk is flagged asentrychunk while theentry1,entry2andvendorsare unflagged asentry.manifestchunk is anentrychunk it contains the runtime.Hope it helps.