一、什么是代码分割(Code Splitting):
1、在最开始使用Webpack的时候, 我们是将所有的js文件全部打包到一个build.js(出口)文件中, 但是在大型项目中, build.js可能过大, 导致页面加载时间过长. 这个时候就需要code splitting, code splitting就是将文件分割成块(chunk), 我们可以定义一些分割点(split point), 根据这些分割点对文件进行分块, 并实现按需加载。
2、自己的一点理解:针对单页面应用,代码分割,就是将除了入口文件中的JS直接打包到出口文件中,在入口文件中引入的其他模块(无论是通过npm安装的第三方模块还是自己定义的第三方模块),都按照块去分割;
这样做的优点:
(1)在加载某个页面的时候只加载本页面用到的JS,而不是将所有的JS代码,有效的节省了页面的加载效率;
(2)对于npm安装的第三方模块,代码基本上不会有什么变化,当我们按照模块去打包后,就可以使用这个模块的缓存,充分利用了浏览器的缓存,也节约了资源;
二、如何在webpack中使用代码分割:
1、对于异步引入组建的方式,我们无需配置webpack,webpack会自动帮我们去进行代码分割;(这里不做重点);
// 异步引入lodash组件,webpack会自动帮我们去做代码分割;
function getComponent() {
return import('lodash').then(({
default: _
}) => {
var element = document.createElement('div');
element.innerHTML = _.join(['Dell', 'Lee'], '-');
return element;
})
}
getComponent().then(element => {
document.body.appendChild(element);
})
2、对于同步引入的组件,我们需要去配置webpack:
(1)webpack底层去做代码分割使用的插件是 SplitChunkPlugin;
(2)SplitChunkPlugin插件的配置:
let path = require('path');
// 引入HtmlWebpackPlugin插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 引入clean-webpack-plugin插件
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
entry:{...省略},,
module: {
rules: [
// file-loader的配置规则
{...省略},
// url-loader的配置规则
{...省略},
// postcss-loader的配置
{...省略},
output:{...省略},,
plugins: [new HtmlWebpackPlugin({
template: './src/index.html'
}), new CleanWebpackPlugin()],
optimization: {
splitChunks: {
chunks: 'all',
minSize: 30000,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
filename: 'vendors.js'
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
filename: 'common.js'
}
}
}
}
}
1、chunks:
(1)'async' 表示此配置项只对异步引入方式生效;
(2)'initial' 表示此配置项只对同步 引入方式生效;
(3)'all' 表示此配置项对同步异步引入方式都生效;
2、minSize:表示只有引入的第三方模块体积大于指定的值,代码的配置项才会有效;一般我们配置成30000也就是30kb;
3、maxSize:这个配置项不是说超过了这个体积限制就不做代码分割,而是,如果第三方库超过了这个最大限制,我们可能会对分割后的第三方库再进行分割,这个要根据这个库是否支持再次分割;因此一般这个参数我们会配置成0;
4、minChunks:这个配置项是指第三方库至少在项目中引用了多少次才会做代码分割;比如,我们配置为2,但是lodash在项目中只引用了一次,那么我们不会对lodash进行代码分割;
5、maxAsyncRequests:这个配置项是指我们最多对多少个第三方库做代码分割,比如我们在项目中引入了10个第三方库,maxAsyncRequests为5,那么我们只对前五个库做代码分割,分割成三个js文件,后面的五个就不做代码分割;
6、maxInitialRequests:这个配置参数是指对入口文件引入的第三方库,我们最多分割几个库;比如,我们的maxInitialRequests为3,那么只对入口文件中引入的前三个第三方库做代码分割,并且分割成3个JS文件;其余的不做分割;
7、automaticNameDelimiter:是指当我们不指定分割出来的库的JS文件的名字时,会自动在文件名中间添加的符号;
8、name:是指,是否根据cacheGroups中的配置去定义分割出的文件名字;一般使用默认配置true;
9、cacheGroups:字面意思,缓存组,是配合其配置项vendors和default一起使用的,作用是当我们对一个JS文件进行打包的时候,我们碰到需要分割的第三方库时,并不是立马将其分割,而是将其缓存下来,等到整个第三方库都分析完了,根据是符合vendors组,还是符合default组,再将其打包到一个文件中去;
10、vendors:组,根据其中的test去划分,如果这个第三方模块来自test的匹配项,也就是node_modules,则将其划分到vendors组;
(1)test:匹配来自哪个文件夹中;
(2)filename:分割生成的JS文件的名字;
(3)priority:优先级,如果打包的第三方库既符合vendors组,又符合default组,会根据priority的大小确定使用哪个组的规则,如果vendors组的priority大,则使用vendors组的配置规则分割;
11、default:默认分组,当分割代码的时候,无论第三方库是否符合vendors组的配置,都会走到default组,当然会根据priority的优先级确定分组;
(1)reuseExistingChunk:不会对多次引用的第三方库进行重复打包,会复用之前打包好的相同模块;
总结:分割规则,当对业务代码进行打包时,遇到引入的第三方模块时,webpack会进入到optimization插件的配置中,从上到下依次确定是否符合分割的各个规则,先走:chunks,确定对同步引入还是异步引入有效;
依次minSize、maxSize、minChunks、maxAsyncRequests、maxInitialRequests、automaticNameDelimiter、name、cacheGroups,不符合则不分割;