webpack4之splitChunks代码分割
前言
webpack4.0使用splitChunks替代CommonsChunksPlugin插件进行代码分割,这篇文章主要针对splitChunks的chunks与cacheGroups进行研究。
代码分割的理念
首先搞明白: webpack里的代码分割是个什么鬼? 它允许你将一个文件分割成多个文件。如果使用的好,它能大幅提升你的应用的性能。其原因是基于浏览器会缓存你的代码这一事实。每当你对某一文件做点改变,访问你站点的人们就要重新下载它。然而依赖却很少变动。如果你将(这些依赖)分离成单独的文件,访问者就无需多次重复下载它们了。
使用webpack生成一个或多个包含你源代码最终版本的“打包好的文件”(bundles),(概念上我们当作)它们由(一个一个的)chunks组成。
splitChunks
splitChunks不配置也会生效,源于他的默认配置:
optimization: {
splitChunks: {
chunks: 'async',
minSize: 30000,
minRemainingSize: 0,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 6,
maxInitialRequests: 4,
automaticNameDelimiter: '~',
cacheGroups: {
defaultVendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
}
-
chunks配置
1、 async表示只从异步加载得模块(动态加载import())里面进行拆分
2、initial表示只从入口模块进行拆分
3、all表示以上两者都包括
-
cacheGroups配置
cacheGroups其实是splitChunks里面最核心的配置,一开始我还认为cacheGroups是可有可无的,这是完全错误的,splitChunks就是根据cacheGroups去拆分模块的,包括之前说的chunks属性和之后要介绍的种种属性其实都是对缓存组进行配置的。splitChunks默认有两个缓存组:vender和default
它的test设置为 /[\/]node_modules[\/]/ 表示只筛选从node_modules文件夹下引入的模块,所以所有第三方模块才会被拆分出来。除此之外还有一个default缓存组,它会将至少有两个chunk引入的模块进行拆分,它的权重小于vendors
代码演示
index.js
import React from 'react'
import ReactDOM from 'react-dom'
const App = () => {
let Page1 = null
import(/* webpackChunkName: "page1" */'./page1').then(comp => {
Page1 = comp
})
return (
<div>
<div>App</div>
<Page1 />
</div>
)
}
ReactDOM.render(<App />, document.getElementById('root'));
page1.js
import React from 'react'
import _ from 'lodash'
const Page1 = () => {
return (
<div>
<div>Page1</div>
</div>
)
}
export default Page1
optimization:{
splitChunks:{
chunks:'all'
}
}
输出:
image.png
输出vendors~main.js是因为thunks设置为true,因此不光会分割异步加载的还会分割入口模块加载的。
其中vendors~main.js与vendors~page1.js就是因为cacheGroups里面定义了vendors这个缓存组,它的test设置为 /[\/]node_modules[\/]/ 表示只筛选从node_modules文件夹下引入的模块,所以所有第三方模块才会被拆分出来。除此之外还有一个default缓存组,它会将至少有两个chunk引入的模块进行拆分。
cacheGroups中priority代表权重,default中priority权重为-20,defaultVendors默认权重为-10,因此当2者有冲突时候会优先按照defaultVendors执行。