有人可以解释 Webpack 的 CommonsChunkPlugin
Can someone explain Webpack's CommonsChunkPlugin
我得到了 CommonsChunkPlugin
查看所有入口点的一般要点,检查它们之间是否有共同点 packages/dependencies 并将它们分成自己的包。
那么,假设我有以下配置:
...
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
的完整代码并包含运行时
这样我们最终得到了一些较小的包,运行时包含在 commons
包中。还可以,但不理想。
案例 2: 如果我通过 { name : 'vendors' }
我将得到以下捆绑文件:
entry1.bundle.js
包含来自 entry1.js
的完整代码,jquery
的要求,但不包含运行时
entry2.bundle.js
包含来自 entry2.js
的完整代码,jquery
的要求,但不包含运行时
vendors.bundle.js
其中包含 jquery
和 some_jquery_plugin
的完整代码并包含运行时。
这样,我们最终还是得到了一些较小的整体包,但运行时现在包含在 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
包中。这是理想情况。
我不明白understand/I我不确定我是否理解
在 CASE 2 为什么我们最终得到包含公共代码(jquery
)和其他任何东西的 vendors
包保留在 vendors
条目 (some_jquery_plugin
) 中?根据我的理解,CommonsChunkPlugin
在这里所做的是它收集了公共代码(jquery
),并且由于我们强制将其输出到 vendors
包,所以它有点 "merged" 将公共代码放入 vendors
包(现在只包含来自 some_jquery_plugin
的代码)。 请确认或说明。
在 CASE 3 我不明白当我们将 { names : ['vendors', 'manifest'] }
传递给插件时发生了什么。 Why/how 是 vendors
包保持完整,同时包含 jquery
和 some_jquery_plugin
,而 jquery
显然是一个共同的依赖项,为什么生成的 manifest.bundle.js
文件以其创建方式创建(需要所有其他包并包含运行时)?
这就是 CommonsChunkPlugin
的工作原理。
公共块 "receives" 由多个入口块共享的模块。
可以在 Webpack repository.
中找到复杂配置的一个很好的示例
在Webpack的优化阶段CommonsChunkPlugin
是运行,这意味着它在内存中运行,就在块被密封并写入磁盘之前。
当定义了几个公共块时,它们是按顺序处理的。在你的案例 3 中,它就像 运行 插件两次。但请注意,CommonsChunkPlugin
可以有更复杂的配置(minSize、minChunks 等),这会影响模块的移动方式。
案例 1:
- 有 3 个
entry
块(entry1
、entry2
和 vendors
)。
- 配置将
commons
块设置为公共块。
- 插件处理
commons
公共块(因为块不存在,所以创建):
- 它收集在其他块中多次使用的模块:
entry1
、entry2
和 vendors
使用 jquery
因此模块从这些块中删除块并添加到 commons
块。
commons
块被标记为 entry
块,而 entry1
、entry2
和 vendors
块未标记为 entry
.
- 最后,由于
commons
块是一个 entry
块,它包含 运行 时间和 jquery
模块。
案例 2:
- 有 3 个
entry
块(entry1
、entry2
和 vendors
)。
- 配置将
vendors
块设置为公共块。
- 插件处理
vendors
公共块:
- 它收集在其他块中多次使用的模块:
entry1
和 entry2
使用 jquery
因此模块从这些块中删除(注意它是未添加到 vendors
块,因为 vendors
块已包含它)。
vendors
块被标记为 entry
块,而 entry1
和 entry2
块未标记为 entry
。
- 最后,由于
vendors
块是一个entry
块,它包含运行时间和jquery
/jquery_plugin
模块。
案例 3:
- 有 3 个
entry
块(entry1
、entry2
和 vendors
)。
- 配置将
vendors
块和manifest
块设置为普通块。
- 插件创建
manifest
块,因为它不存在。
- 插件处理
vendors
公共块:
- 它收集在其他块中多次使用的模块:
entry1
和 entry2
使用 jquery
因此模块从这些块中删除(注意它是未添加到 vendors
块,因为 vendors
块已包含它)。
vendors
块被标记为 entry
块,而 entry1
和 entry2
块未标记为 entry
。
- 插件处理
manifest
公共块(由于块不存在,所以创建):
- 它收集在其他块中被多次使用的模块:因为没有模块被多次使用,所以没有模块被移动。
manifest
块被标记为 entry
块,而 entry1
、entry2
和 vendors
未标记为 entry
。
- 最后,由于
manifest
块是一个 entry
块,它包含 运行 时间。
希望对您有所帮助。
我得到了 CommonsChunkPlugin
查看所有入口点的一般要点,检查它们之间是否有共同点 packages/dependencies 并将它们分成自己的包。
那么,假设我有以下配置:
...
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
的完整代码并包含运行时
这样我们最终得到了一些较小的包,运行时包含在
commons
包中。还可以,但不理想。案例 2: 如果我通过
{ name : 'vendors' }
我将得到以下捆绑文件:entry1.bundle.js
包含来自entry1.js
的完整代码,jquery
的要求,但不包含运行时entry2.bundle.js
包含来自entry2.js
的完整代码,jquery
的要求,但不包含运行时vendors.bundle.js
其中包含jquery
和some_jquery_plugin
的完整代码并包含运行时。
这样,我们最终还是得到了一些较小的整体包,但运行时现在包含在
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
包中。这是理想情况。
我不明白understand/I我不确定我是否理解
在 CASE 2 为什么我们最终得到包含公共代码(
jquery
)和其他任何东西的vendors
包保留在vendors
条目 (some_jquery_plugin
) 中?根据我的理解,CommonsChunkPlugin
在这里所做的是它收集了公共代码(jquery
),并且由于我们强制将其输出到vendors
包,所以它有点 "merged" 将公共代码放入vendors
包(现在只包含来自some_jquery_plugin
的代码)。 请确认或说明。在 CASE 3 我不明白当我们将
{ names : ['vendors', 'manifest'] }
传递给插件时发生了什么。 Why/how 是vendors
包保持完整,同时包含jquery
和some_jquery_plugin
,而jquery
显然是一个共同的依赖项,为什么生成的manifest.bundle.js
文件以其创建方式创建(需要所有其他包并包含运行时)?
这就是 CommonsChunkPlugin
的工作原理。
公共块 "receives" 由多个入口块共享的模块。 可以在 Webpack repository.
中找到复杂配置的一个很好的示例在Webpack的优化阶段CommonsChunkPlugin
是运行,这意味着它在内存中运行,就在块被密封并写入磁盘之前。
当定义了几个公共块时,它们是按顺序处理的。在你的案例 3 中,它就像 运行 插件两次。但请注意,CommonsChunkPlugin
可以有更复杂的配置(minSize、minChunks 等),这会影响模块的移动方式。
案例 1:
- 有 3 个
entry
块(entry1
、entry2
和vendors
)。 - 配置将
commons
块设置为公共块。 - 插件处理
commons
公共块(因为块不存在,所以创建):- 它收集在其他块中多次使用的模块:
entry1
、entry2
和vendors
使用jquery
因此模块从这些块中删除块并添加到commons
块。 commons
块被标记为entry
块,而entry1
、entry2
和vendors
块未标记为entry
.
- 它收集在其他块中多次使用的模块:
- 最后,由于
commons
块是一个entry
块,它包含 运行 时间和jquery
模块。
案例 2:
- 有 3 个
entry
块(entry1
、entry2
和vendors
)。 - 配置将
vendors
块设置为公共块。 - 插件处理
vendors
公共块:- 它收集在其他块中多次使用的模块:
entry1
和entry2
使用jquery
因此模块从这些块中删除(注意它是未添加到vendors
块,因为vendors
块已包含它)。 vendors
块被标记为entry
块,而entry1
和entry2
块未标记为entry
。
- 它收集在其他块中多次使用的模块:
- 最后,由于
vendors
块是一个entry
块,它包含运行时间和jquery
/jquery_plugin
模块。
案例 3:
- 有 3 个
entry
块(entry1
、entry2
和vendors
)。 - 配置将
vendors
块和manifest
块设置为普通块。 - 插件创建
manifest
块,因为它不存在。 - 插件处理
vendors
公共块:- 它收集在其他块中多次使用的模块:
entry1
和entry2
使用jquery
因此模块从这些块中删除(注意它是未添加到vendors
块,因为vendors
块已包含它)。 vendors
块被标记为entry
块,而entry1
和entry2
块未标记为entry
。
- 它收集在其他块中多次使用的模块:
- 插件处理
manifest
公共块(由于块不存在,所以创建):- 它收集在其他块中被多次使用的模块:因为没有模块被多次使用,所以没有模块被移动。
manifest
块被标记为entry
块,而entry1
、entry2
和vendors
未标记为entry
。
- 最后,由于
manifest
块是一个entry
块,它包含 运行 时间。
希望对您有所帮助。