该文章内容大抵翻译自
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
的例子。这些用例仅仅展示了它在默许设置下的行动。你也可以运用分外设置项来举行个性化定制。
提醒:
- 可以经由过程
optimization.splitChunks
举行设置。这里的例子是关于文件的,默许情况下仅适用于异步加载的文件块。但也可以增加optimization.splitChunks.chunks: "all"
来设置适用于一切范例的文件。 - 我们假定每一个分外导入的库文件都大于30kb,由于优化仅在该体积以后最先举行。(可以经由过程设置
minSize
属性举行修正,默许 30000)
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将会自动建立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
: react, react-dom, some components -
chunk-b
: react, react-dom, lodash, some other components -
chunk-c
: react, react-dom, lodash, some components
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
: vue, some components, some shared components -
chunk-b
: vue, some other components, some shared components -
chunk-c
: vue, some more components, some shared components
假定一切的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
: 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将会建立2个库文件及2个通用组件文件
-
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 chunk-b chunk-c chunk-d
: Only the components
提醒:由于天生的导入文件名称包括一切的原始文件名称,所以我们推荐在临盆环境中运用的长效缓存文件不要包括[name]
在文件名中,或许设置optimization.splitChunks.name: false
来封闭文件名天生逻辑。如许纵然在后续开辟中对该文件增加了新的援用,也不会修正文件名,该缓存逻辑依旧见效。