我得到的一般要点是,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
的参数,将发生以下任何一种情况:
***CASE 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
中的完整代码,并包含运行时
这样我们最终得到了一些更小的包,运行时包含在commons
包中。
***案例2:**如果我传递{ name : 'vendors' }
,我将得到以下包文件:
entry1.bundle.js
,包含entry1.js
的完整代码(jquery
的要求),不包含运行时entry2.bundle.js
,包含entry2.js
的完整代码,这是jquery
的一个要求,但不包含运行时vendors.bundle.js
,其中包含jquery
和some_jquery_plugin
的完整代码,并包含运行时。
这样,我们最终得到了一些更小的bundle,但是运行时现在包含在vendors
bundle中,这比上一个情况要差一些,因为运行时现在包含在vendors
bundle中。
***案例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
,它包含每个其他捆绑包的要求,并包含运行时
这样我们就得到了一些更小的bundle,运行时包含在manifest
bundle中,这是理想的情况。
我不明白/我不确定我是否明白
- 在CASE 2中,为什么我们最终得到的
vendors
捆绑包包含两个公共代码(jquery
)以及vendors
项中剩余的内容(some_jquery_plugin
)?据我所知,CommonsChunkPlugin
在这里所做的是收集公共代码(jquery
),并且由于我们强制它将其输出到vendors
bundle,因此它将通用代码“合并”到vendors
bundle中(现在只包含some_jquery_plugin
中的代码)。请确认或解释。 - 在案例3中,我不明白当我们将
{ names : ['vendors', 'manifest'] }
传递给插件时发生了什么。当jquery
显然是一个公共依赖项时,为什么/如何保持vendors
包的完整性,包含jquery
和some_jquery_plugin
,为什么生成的manifest.bundle.js
文件是按照它的创建方式创建的(需要所有其他bundle并包含运行时)?
1条答案
按热度按时间l0oc07j21#
这就是
CommonsChunkPlugin
的工作原理。一个公共块"接收"由几个入口块共享的模块。在Webpack repository中可以找到一个复杂配置的好例子。
CommonsChunkPlugin
在Webpack的优化阶段运行,这意味着它在内存中运行,就在块被密封并写入磁盘之前。当定义了几个公共块时,它们会按顺序处理。在您的情况3中,这就像运行插件两次。但请注意,
CommonsChunkPlugin
可以有一个更复杂的配置(minSize,minChunks等),这会影响模块移动的方式。1.有3个
entry
区块(entry1
、entry2
和vendors
)。1.配置将
commons
块设置为公共块。1.插件处理
commons
公共块(由于块不存在,因此创建):1.它收集在其他块中多次使用的模块:
entry1
、entry2
和vendors
使用jquery
,因此模块从这些块中删除并添加到commons
块。commons
块被标记为entry
块,而entry1
、entry2
和vendors
块未被标记为entry
。1.最后,由于
commons
块是entry
块,因此它包含运行时和jquery
模块。1.有3个
entry
区块(entry1
、entry2
和vendors
)。1.配置将
vendors
块设置为公共块。1.该插件处理
vendors
公共块:1.它收集在其他块中多次使用的模块:
entry1
和entry2
使用jquery
,因此模块从这些块中移除(注意,它没有被添加到vendors
块,因为vendors
块已经包含它)。vendors
块被标记为entry
块,而entry1
和entry2
块未被标记为entry
。1.最后,由于
vendors
块是entry
块,因此它包含运行时和jquery
/jquery_plugin
模块。1.有3个
entry
区块(entry1
、entry2
和vendors
)。1.配置将
vendors
块和manifest
块设置为公共块。1.插件创建
manifest
块,因为它不存在。1.插件处理
vendors
公共块:1.它收集在其他块中多次使用的模块:
entry1
和entry2
使用jquery
,因此模块从这些块中移除(注意,它没有被添加到vendors
块,因为vendors
块已经包含它)。vendors
块被标记为entry
块,而entry1
和entry2
块未被标记为entry
。1.插件处理
manifest
公共块(由于块不存在,因此创建):1.它收集在其他块中多次使用的模块:由于没有模块被使用超过一次,因此没有模块被移动。
manifest
块被标记为entry
块,而entry1
、entry2
和vendors
未被标记为entry
。1.最后,由于
manifest
块是entry
块,因此它包含运行时。