Code Split
打包代码时会将所有的js打包到一个文件夹中,代码体积太大,如果我们只要渲染首页,就应该只加载首页的js代码,其它文件不加载。
所以我们需要将打包生成的文件进行代码分割,生成多个js文件,渲染哪个页面的js文件,就只加载某个js文件,这样加载的文件就少,速度更快。
代码分割(code split)主要做两件事
- 分割文件:将打包生成的文件进行分割,生成多个js文件
- 按需加载:需要哪个文件就加载那个文件
怎么使用呢?
1. 多文件打包入口
const path = require('path')
const HtmlwebpackPlugin = require("html-webpack-plugin")
module.exports = {
entry:{
//有多个入口文件,entry为对象模式
main: './src/main.js',
app: './src/app.js'
},
output:{
path: path.resolve(__dirname, 'dist')
filename: '[name].js'// webpack命名方式,[name]为文件自己命名: main、app
},
plugins:[
new HtmlwebpackPlugin({
template: path.resolve(__dirname, "./public/index.html")
})
],
mode: 'production'
}
多个打包入口就有多个输出
2. 提取公共模块
如果多个入口使用了同一份代码,我们可以把这一份代码单独提取打包。
我们需要使用到 cplitChunks 配置 参考地址
module.exports = {
//...
optimization: {
splitChunks: {
chunks: 'async',//三选一:"initial" 初始化,"all"(默认就是all),"async"(动态加载)
minSize: 20000,//当导入的模块最小是多少字节才会进行代码分割 也就是说chunk体积大于20kb才会拆分。
minRemainingSize: 0,// 类似于minSize,最后确保提取的文件大小不能为0
minChunks: 1,//当一个模块被导入(引用)至少多少次才对该模块进行代码分割
maxAsyncRequests: 30,//按需加载时的最大并行请求数
maxInitialRequests: 30,//入口点的最大并行请求数
enforceSizeThreshold: 50000,//超过50kb一定会单独打包(会忽略minRemainingSize,maxAsyncRequests,maxInitialRequests)
cacheGroups: {//缓存组,这里是我们表演的舞台,抽取公共模块什么的,都在这个地方
defaultVendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,//优先级
reuseExistingChunk: true,
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,reuseExistingChunk: true, //当已经存在分割时,使用已经存在且分割好的模块
},
},
},
},
};
字段解析
- chunks
all模式下,包括所有类型的chunks都进行分割 initial: 会将入口文件中的依赖包重新切割为一个新的文件,其他文件中动态引入的不会进行拆分,和async优点相反。
- cacheGroups
缓存组,这里配置抽取模块
- priority: 优先级,决定执行的顺序
- minSize: 最小大小, 当抽取的公共模块大于minSize所设置的值才起作用
- minChunk: 最小块, 当块的数量大于等于minChunks时,才起作用
- maxSize: 如果引入的包已经超过了设置的最大值,那么webpack会尝试对该包再进行分割
3. 按需加载动态导入
想要实现按需加载,动态导入模块, 需要使用导入语法 import()
- main.js
document.getElementById('btn').onclick = function () {
import ('./count.js')
.then(res => {
res.default(4, 1)
})
}
- public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<button id="btn">按钮</button>
</body>
</html>