Webpack 4.0 CommonsChunkPlugin 和 optimization splitChunks

栏目: JavaScript · 发布时间: 6年前

内容简介:该文章内容大致翻译自webpack 4.0 对代码模块的关系图进行了一些巨大的优化,同时添加了一个新的先让我们看看旧版关系图的一些缺陷。

该文章内容大致翻译自 webpack 4: Code Splitting, chunk graph and the splitChunks optimization

原有的问题

webpack 4.0 对代码模块的关系图进行了一些巨大的优化,同时添加了一个新的 optimization 用于模块的分离(可以看做是对 CommonsChunkPlugin 的一次优化)。

先让我们看看旧版关系图的一些缺陷。

在之前的版本中,我们将各个模块打包进编译后的文件之中,同时这些文件之间又是通过 父子关系 来进行关联,最后将我们整个项目中的所有模块串联起来。

当其中一个文件含有父级引用,那我们可以推断出,在该文件完成加载时,已经成功加载了父级文件。那么我们可以据此进行一些优化。比如当一个文件中的模块已经在父级文件中正常运行,那么我们可以将该模块从文件中移除,因为它必然已经被成功加载。

在入口点或异步拆分点处引用这些文件。这些文件将会并行加载。

这种类型的关系图使得分离 splitting 变得非常困难。比如在你使用 CommonsChunkPlugin 插件时。会有一个或多个文件内模块被移动到新的文件中来。这一整个新文件需要被添加到关系图中来。但我们应该如何设置它的层级呢?作为旧有文件的父级?还是子级? CommonsChunkPlugin 中将其设置为父级,但从技术层面来说,这是错误的,并且导致了一些负面的优化结果(提前加载的这个文件中的部分模块不是必需的)。

现在新的关系图中,引入了一个新概念: ChunkGroup 。包含文件列表的文件分组。

在入口点或异步拆分点处我们会引用这个文件分组,该分组内的文件全都是并行加载。而一个文件可以被多个文件分组引用(但不会多次加载)。

现在不再使用父子级的关系来描述文件之间的联系,取而代之的是文件分组 ChunkGroup

那么此时, splitting 文件就能够被表述出来。被创建的新文件可以被添加到所有包含原始文件的文件分组中。同时也不会因此产生负面优化效果。

CommonsChunkPlugin和SplitChunksPlugin的区别

这个问题被修复之后,我们可以更多的使用文件拆分了。我们可以将任何文件拆分出来并且不需要提高其加载优先级。

CommonsChunkPlugin 存在以下这些问题:

  • 需要下载当前还不需要使用的代码文件。
  • 异步加载使用文件效率低下。
  • 很难使用。(猜测这里指的是配置)
  • 实现方式很难理解。

所以新的插件诞生了: SplitChunksPlugin

它会使用模块引用计数和模块类别区分(比如:node_modules)来自动分离出需要被拆分的文件内引用模块。

There is a paradigm shift here. The CommonsChunkPlugin was like: “Create this chunk and move all modules matching minChunks into the new chunk”. The SplitChunksPlugin is like: “Here are the heuristics, make sure you fullfil them”. (imperative vs declarative)

这里没有理解全部的内容。

SplitChunksPlugin 同时提供了更多的特性:

  • 不会加载非必须文件(除非进行了强制合并)
  • 异步文件处理更有效率。
  • 默认异步处理文件。
  • 它将引用模块分散到多个库文件中。
  • 更容易使用。
  • 不依赖文件引用关系图。
  • 更加的自动化。

例子

下面是一些使用 SplitChunksPlugin 的例子。这些用例仅仅展现了它在默认配置下的行为。你也可以使用额外配置项来进行个性化定制。

提示:

  1. 可以通过 optimization.splitChunks 进行配置。这里的例子是关于文件的,默认情况下仅适用于异步加载的文件块。但也可以添加 optimization.splitChunks.chunks: "all" 来配置适用于所有类型的文件。
  2. 我们假定每个额外导入的库文件都大于30kb,因为优化仅在该体积之后开始进行。(可以通过配置 minSize 属性进行修改,默认 30000)

Vendors

chunk-a
chunk-b
chunk-c
chunk-d

webpack将会自动创建2个库文件:

  • vendors~chunk-a~chunk-b : react, react-dom
  • vendors~chunk-c~chunk-d : angular
  • chunk-a chunk-b chunk-c chunk-d : 含有components

Vendors overlapping

chunk-a
chunk-b
chunk-c

webpack依然会创建2个库文件:

  • vendors~chunk-a~chunk-b~chunk-c : react, react-dom
  • vendors~chunk-b~chunk-c : lodash
  • chunk-a chunk-b chunk-c : 含有components

Shared modules

chunk-a
chunk-b
chunk-c

假设所有的 shared components 体积都大于 30kb,webpack将会创建一个库文件和一个通用组件文件:

  • vendors~chunk-a~chunk-b~chunk-c : vue
  • commons~chunk-a~chunk-b~chunk-c : some shared components
  • chunk-a chunk-b chunk-c : 含有components

当这些 shared components 体积小于30kb是,webpack会故意将该模块复制到 chunk-a chunk-b chunk-c 三个文件中。我们认为进行分离所减小的加载体积的整体效果并不如一次额外的加载请求的消耗。

Multiple shared modules

chunk-a
chunk-b
chunk-c
chunk-d

webpack将会创建2个库文件及2个通用组件文件

vendors~chunk-a~chunk-b~chunk-c
vendors~chunk-b~chunk-c~chunk-d
commons~chunk-a~chunk-c
commons~chunk-c~chunk-d

chunk-a chunk-b chunk-c chunk-d : Only the components

提示:因为生成的导入文件名称包含所有的原始文件名称,所以我们推荐在生产环境中使用的长效缓存文件不要包含 [name] 在文件名中,或者设置 optimization.splitChunks.name: false 来关闭文件名生成逻辑。这样即使在后续开发中对该文件添加了新的引用,也不会修改文件名,该缓存逻辑依然生效。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Shallows

The Shallows

Nicholas Carr / W. W. Norton & Company / 2010-6-15 / USD 26.95

"Is Google making us stupid?" When Nicholas Carr posed that question, in a celebrated Atlantic Monthly cover story, he tapped into a well of anxiety about how the Internet is changing us. He also crys......一起来看看 《The Shallows》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器