这是小弟第一次翻译,虽自己理解了其精华,但无法精准表达,还望海涵。

webpack 4对块图进行了一些重大改进,并增加了对 chunk 拆分的新优化(这是对 CommonsChunkPlugin 的一种改进)。

让我们看看之前的块图存在的缺点。

之前的块图通过父子关系连接到其他块,chunk 包含模块。

当一个块有父母时,可以假定在加载时至少有一个父母已经加载了。这些信息可以被优化步骤所使用。当 chunk
中的模块在所有父母中都使用时,就可以把这个模块提取出来,因为它在任何情况下都需要使用。

在入口或者异步分割点引用这些 chunk 。这些 chunk 是并行加载的。

这种图形很难理解 chunks 的分割。例如在使用 CommonChunkPlugin 的时候,从一个或多个 chunks
删除模块并放入一个新模块,这个新模块需要连接到块图中。但是应该怎么定位这个新模块?作为之前 chunk 的父母?作为孩子? 在
CommonChunkPlugin 中将其添加为父母,但是从技术角度上这是错误的,也会造成对优化产生很多负作用。

新的块图引入了一个新对象:ChunkGroup. 一个ChunkGroup包含一个Chunks.

在入口点或异步分割点处引用一个ChunkGroup,这就意味着包含所有并行的Chunks。一个Chunk可以被引用在多个ChunkGroup中。

Chunk之间不再存在父子关系,ChunkGroups 之间也不存在这种关系。

现在 Chunks 的分割可以被理解了,因为新的Chunks被添加到所有包含原始 Chunk 的 ChunkGroups 中,这并不会影响父母关系。

现在解决了这个问题,我们可以开始更多的使用Chunk分割。我们可以拆分任何 chunk,而不用担心破坏块图。
CommonsChunkPlugin存在很多问题:

它可能导致下载更多的超过我们使用的代码
它在异步chunks中是低效的。
配置繁琐,很难使用
难以被理解
所以一个新的插件诞生了: SplitChunksPlugin

它使用模块重复计数和模块类别(如 node_modules ),通过 heuristics 自动识别应该被分块的模块,并分割 chunks。

这有个两者的比喻,CommonsChunkPlugin就好像: 创建一个所有模块中都共同存在的模块。 而SplitChunksPlugin就像是:“Here
are the heuristics, make sure you fullfil them”

SplitChunksPlugin 也有着不错的特点:

不会下载不需要的代码
对异步chunks也很高效
被默认用于异步chunks
可以通过多个vendor chunks来进行vender的分割
使用简单
不依赖块图
基本上是自动的
这里有一些SplitChunksPlugin会为你做的例子。这些示例仅显示默认行为。有更多的可能性与额外的配置。


您可以通过optimization.splitChunks进行配置。这些示例提到了有关块的内容,默认情况下,它仅适用于异步块,但对于optimization.splitChunks.chunks:“all”对于初始块也是如此。

我们假设这里使用的每个外部库都大于30kb,因为优化仅在该阈值之后进行。

Vendors
chunk-a: react, react-dom, some components

chunk-b: react, react-dom, some other components

chunk-c: angular, some components

chunk-d: angular, some other components

webpack 会自动创建两个 vendors chunks, 结果如下:

vendors~chunk-a~chunk-b: react, react-dom

vendors~chunk-c~chunk-d: angular

chunk-a to chunk-d: Only the components

Vendors 重叠
chunk-a: react, react-dom, some components

chunk-b: react, react-dom, lodash, some other components

chunk-c: react, react-dom, lodash, some components

webpack 会自动创建两个 vendors chunks, 结果如下:

vendors~chunk-a~chunk-b~chunk-c: react, react-dom

vendors~chunk-b~chunk-c: lodash

chunk-a to chunk-c: Only the components

共享模块
chunk-a: vue, some components, some shared components

chunk-b: vue, some other components, some shared components

chunk-c: vue, some more components, some shared components

假设共享组件的大小大于30kb,webpack将创建vendors chunk 和一个a commons chunk,结果如下:

vendors~chunk-a~chunk-b~chunk-c: vue

commons~chunk-a~chunk-b~chunk-c: some shared components

chunk-a to chunk-c: Only the components

When the size of the shared components is smaller than 30kb, webpack
intentionally duplicates the modules in chunk-a to chunk-c. We think reduces
download size is not worth the extra request needed for a separate chunk load.

多个共享模块
chunk-a: react, react-dom, some components, some shared react components

chunk-b: react, react-dom, angular, some other components

chunk-c: react, react-dom, angular, some components, some shared react
components, some shared angular components

chunk-d: angular, some other components, some shared angular components
webpack将创建两个vendors chunks和两个commons chunks

vendors~chunk-a~chunk-b~chunk-c: react, react-dom

vendors~chunk-b~chunk-c~chunk-d: angular

commons~chunk-a~chunk-c: some shared react components

commons~chunk-c~chunk-d: some shared angular components

chunk-a to chunk-d: Only the components

Note: Since the chunk name includes all origin chunk names it’s recommended
for production builds with long term caching to NOT include [name] in the
filenames, or switch off name generation via optimization.splitChunks.name:
false. Elsewise files will invalidate i. e. when more chunks with the same
vendors are added.


由于块名称包含所有源块名称,因此建议在生产环境下使用来达到长期缓存,以避免在文件名中包含[name].或者通过optimization.splitChunks.name关闭名称生成:false。其他文件将使我无效。即当添加更多与同一vendors的块时。

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信