什么是SplitChunkPlugin?
- 说到SplitChunkPlugin就不得不提Code Splitting(代码分割),Code Splitting顾名思义就是对你的代码进行分割,为什么要对代码进行分割?主要是为了优化网站的性能,举个例子:当你的页面只有一个js文件,它有10M大小,那么当用户访问你的页面的时候,就要要一次用一个请求加载10M大小的文件;而当你使用了代码分割,把这个js文件分割成了2个5M大小的文件,那么用户访问你的页面的时候就会用两个请求同时加载2个5M大小的js文件。在大部分时候加载2个5M的文件都是比加载一个10M的文件要快的。
- 在平时我们怎么进行代码分割呢?不使用辅助工具的时候,一般都需要我们自己去分析业务代码,然后自己手动分割,这种时候就比较考验个人技巧了,工作量也大。当我们使用Webpack的时候就比较方便了,因为它内置了SplitChunkPlugin插件用来帮助我们进行代码分割。只需要在webpack.config.js里面把它配置好就行,默认情况下webpack只会分割异步加载的模块(例如使用import()加载的模块)。
如何配置使用SplitChunkPlugin?
- 在webpack.config.js的optimization的splitChunks里进行配置,在你没有配置时,webpack内部有一个默认的配置,如下:
optimization: {
splitChunks: {
chunks: "async",
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
}
默认配置里面的配置项都有什么用?
- chunks:告诉webpack应该对什么模块进行代码分割,为initial时只对静态导入的模块进行代码分割,async对动态导入的模块代码进行代码分割,all对所有模块的代码都进行分割(不管是静态导入还是动态导入,推荐使用all)。
- minSize:模块大小大于minSize配置的数字时进行代码分割(单位是byte)。当导入的模块符合chunks的配置之后,会对模块的大小进行检测,当比minSize小时不进行代码分割。
- minChunks:模块被其它chunk的最小引用(导入)次数。引用次数大于等于它配置的次数时会进行代码分割。
- maxAsyncRequests:加载页面时最多可以加载的chunk数。webpack检测到目前已经有maxAsyncRequests配置的那么多个chunk就不会进行代码分割了。
- maxInitialRequests:一个入口点最多可以同时加载的chunk数。webpack检测到目前入口点已经有maxInitialRequests配置的这么多时,将不继续进行代码分割
- automaticNameDelimiter:分割出来的chunk的名字分隔符。一般来说会是缓存组名 + automaticNameDelimiter + 导入这个chunk的入口chunk名,你可以使用magic comment来更改分割出来的chunk的名:
import(/*WebpackChunkName: 'chunk名'*/ lodash)
- name:控制分割chunk的名称(和automaticNameDelimiter以及cacheGroups都有关联)。传true时chunk名为缓存组名 + automaticNameDelimiter + 导入这个chunk的入口chunk名。传false既不启用。也可以传字符串和函数。
- cacheGroups:缓存组(每一个缓存组都是一个chunk),模块符合上面的条件也符合cacheGroups里面的条件时,进行代码分割(Tip:同步导入模块时这个配置必须有,否者不会进行代码分割。默认会有vendors和default两个组,不想用它的时候把它设置为false就行)。
- cacheGroups.某一个缓存组名.test:符合这里配置的的模块会属于这个缓存组。
- cacheGroups.某一个缓存组名.priority:缓存组优先级,这里的值越大优先级越高,例如当一个模块同时符合两个缓存组的条件时,它会属于优先级最高的那一个。
- cacheGroups.某一个缓存组名.minChunks:被引用次数大于等于这里配置的值将属于这个缓存组。
- cacheGroups.某一个缓存组名.reuseExistingChunk:是否可以使用其他chunk里的模块,当这个模块已经在别的分割chunk里的时候,就不会把他放到这个缓存组里了,而是使用别的分割chunk里的这个模块。
Tip