本文全部的内容均基于
webpack@4.42.0
所撰写。阅读本文以前需了解Webpack
的一些基本概念,如:entry
、chunk
、module
等。css
代码分割是 Webpack
最引人注目的特性之一。这个特性容许开发者将代码分割成不一样的包,而后能够按需加载或并行加载这些包。它能够用来实现更小的包,并控制资源加载优先级,若是使用正确,将对加载时间产生重大影响。node
首先介绍一下 Webpack
默认的代码分割策略。webpack
webpack will automatically split chunks based on these conditions:web
- New chunk can be shared OR modules are from the node_modules folder
- New chunk would be bigger than 30kb (before min+gz)
- Maximum number of parallel requests when loading chunks on demand would be lower or equal to 5
- Maximum number of parallel requests at initial page load would be lower or equal to 3
上面这段话来自 Webpack
的官方文档,说的是 Webpack
会在知足下面的条件时自动进行 chunk 的分割 (ps:若是没有特殊配置的话,只有异步加载的 chunk 会自动进行分割)。bash
chunk
能够被共享或者 chunk
里的 module
来自于 node_modules
文件夹chunk
文件大小大于 30kb(压缩前)chunk
内部的最大并行请求数不超过 5 个知足上面的四个条件 Webpack
就认为能够进行代码分割,前两个条件应该比较好理解,这里解释下后两个条件的意思吧:并发
chunk
内部的最大并行请求数不超过 5 个简单来讲就是加载 chunk
所发送的请求不能超过 5 个。举个例子:异步
a.js
依赖了 1.js
、2.js
、3.js
、4.js
这四个文件,且这四个文件知足了代码分割的前两个条件 (被共享且大于 30kb)。这个时候就会分割出五个 chunk
,分别是:a.chunk.js
、1.chunk.js
、2.chunk.js
、3.chunk.js
、4.chunk.js
。此时加载 chunk~a
的并发请求数就刚好是 5 个,编译后的加载代码大体以下:async
// t.e 是加载的 chunk 的方法,t.e 的参数应该是 chunk 的 id,为了容易阅读,我这里用了 chunk 的名称替代。
Promise.all([t.e('1.chunk'),t.e('2.chunk'),t.e('3.chunk'),t.e('4.chunk'),t.e('a.chunk')]).then(() => // do some thing)
复制代码
若是 a.js
又依赖了 5.js
,,这个时候并不会分割出 5.chunk
,由于若是分割出 5.chunk
,那么加载 a.chunk
的请求就是 6
个了, 5.js
的内容会被合并到 a.chunk
中。ui
这里的初始化页面能够理解为加载 entry
,换句话说就是加载 entry
的并行请求的最大数量不超过 3 个,如今就比较好理解了,和上一个条件基本一致,只不过一个是针对 entry
的,一个是针对普通的 chunk
的。这个配置是为了对代码分割的 chunk
数量进行必定的限制,避免分割出太多chunk
致使请求数量过多的状况。spa
要注意的是:
js
之外的请求好比css
。上面介绍的都是 Webpack
代码分割的默认策略,这些策略是 Webpack
团队认为的最佳实践。 若是你在项目有特殊的需求,好比认为默认的 30kb 太大了,你想超过 10kb 就进行分割。Webpack
也提供了咱们一些配置去修改分割策略,这就是 Webpack
中的 optimization.splitChunks
配置,下面就介绍几个比较相对重要的配置,完整的配置能够查看文档。
splitChunks.chunks
function (chunk) | string
chunks
配置的是要针对哪些 chunk
进行代码分割,以前有提到过,默认只会分割异步的加载的 chunk
。chunks
的值为 string
时,有效的值为all
, async
和initial
。
module.exports = {
//...
optimization: {
splitChunks: {
// 分割全部类型的 chunk
chunks: 'all'
}
}
};
复制代码
module.exports = {
//...
optimization: {
splitChunks: {
chunks (chunk) {
// 除了 `my-excluded-chunk` 都进行分割
return chunk.name !== 'my-excluded-chunk';
}
}
}
};
复制代码
splitChunks.minChunks
number
minChunks
指的是在代码分割以前 module
至少被几个 chunk
共享。默认值为1
。
splitChunks.minSize
number
minSize
对应的就是分割策略中的第二个条件中的 30kb
的限制,开发者能够根据项目的实际状况灵活调节它的大小。
splitChunks.maxSize
number
这个配置是设置分割出来的 chunk
的最大文件大小的,默认值为 0
,也就是没有上限。设置了该属性,Webpack
就会尽量地把 chunk
的大小限制在maxSize
的值以内,不过一个完整的module
的代码无法分割成几段,因此该超过仍是会超过的。
你能够经过设置这个属性来分割出更多、更小的 chunk
,不过随之而来的就是更多的加载 chunk
的请求。
splitChunks.maxAsyncRequests
number
maxAsyncRequests
对应的是分割策略中的第三条的配置,默认值为 5
splitChunks.maxInitialRequests
number
maxInitialRequests
对应的是分割策略中的第四条的配置,默认值为 3
splitChunks.cacheGroups
cacheGroups
是 splitChunks
中最核心的配置之一,它的配置项包括 splitChunks.*
下的全部配置,且还多了test
、priority
、reuseExistingChunk
三个配置项。
cacheGroups
中的配置会覆盖 splitChunks
中的配置,并且有优先级之分(经过 priority
设置优先级),cacheGroups
主要的用途是针对不一样的 chunk
设置不一样的分割策略,这能够大大提高代码分割的灵活性,笔者在这里就不详细展开说明使用方法了,感兴趣的能够参考官方文档。