前言
这是webpack实战
系列笔记的第9篇记录——代码分片
,前几篇记录如下:
- 打包第一个应用
- 模块化与模块打包
- 资源输入与输出
- 一切皆模块
- 预处理器【上篇】
- 预处理器——常用loader【下篇】
- 样式文件分离
- 样式预处理
代码分片
“实现高性能应用其中重要的一点就是尽可能的让用户每次只加载必要的资源,优先级不太高的资源则采用延迟加载(懒加载)等技术渐进式的获取,这样可以保证首屏页面加载的速度。 代码分片是Webpack作为打包工具所特有的一项技术,通过这项技术我们可以把代码按照特定的形式进行拆分,使用户按需加载。
通过入口划分代码
通过入口配置进行一些简单有效的代码拆分。
对于web应用来说通常会有一些库和工具是不常变动的,可以将它们放在一个单独的入口中,由该入口产生的资源不会经常更新,因此可以有效地利用客户端缓存,让用户不必在每次请求页面时都让资源重新加载。
代码语言:javascript复制// webpack.config.js
...
entry:{
app: './src/app.js',
lib: ['lib-a', 'lib-b', 'lib-c']
}
代码语言:javascript复制<!--index.html-->
...
<script src="./dist/lib.js"></script>
<script src="./dist/app.js"></script>
这种拆分方法主要适用于那些将接口绑定在全局对象上的库,因为业务代码中的模块无法直接引用库中的模块,而这属于不同的依赖树。
但这样仍会带来新的问题:公共模块与业务模块处于不同依赖树的问题以及很多页面并不需要公共模块的问题。
optimization
在webpack4之前,做代码切片使用的是CommonsChunkPlugin,而在4及之后,取而代之的是optimization。
“optimization.SplitChunks简称optimization,是Webpack4为了改进CommonChunkPlugin而重新设计和实现的代码分片特性。
举例
1. 安装
代码语言:javascript复制// 两种方式二选一
yarn add optimization react
// 或
npm install optimization react
2. a.js & b.js
代码语言:javascript复制// a.js
import React from 'react'
import('./b.js');
document.write('a.js', React.version)
代码语言:javascript复制// b.js
import React from 'react'
console.log('b.js', React.version)
3. webpack配置
代码语言:javascript复制// webpack.config.js
module.exports = {
entry: './src/a.js',
output: {
filename: 'a.js',
publicPath: '/dist/'
},
mode: 'development',
optimization: {
splitChunks: {
chunks: 'all'
}
}
}
4. 打包
代码语言:javascript复制yarn build
// 或
npm run build
结果如图所示:
点击查看大图
特性
首先观察上面的配置,从上面的配置项中可以看到:
- 指定了chunks的值是all,含义是:SplitChunks将会对所有的chunks生效;
- mode:之前也一直在用,其实是Webpack4中新增的配置项,可以针对当前是开发环境还是生产环境自动添加一些对应的Webpack配置。
而从上图打包结果中看,可以看到三个文件包:0.a.js
、a.js
和vendors~main.a.js
。其中,vendors~main.a.js
则是将react提取到了里面。
提取条件
- 提取后的chunk可被共享或者来自node_modules目录。
- 提取后的JS chunk体积大于30kB(压缩和gzip前),CSS chunk体积大于50kB。
- 按需加载过程中,并行请求的资源最大值小于等于5。
- 首次加载时,并行请求的资源数最大值小于等于3。
需要注意的是,默认提取方式为异步提取。
配置
分为四类:
- 匹配模式 通过chunks可以配置Splitchunks的工作模式:async(默认),initial和all。async即只提取异步chunk,initial只对入口chunk生效,all则两种模式同时开启。
- 匹配条件 minSize、minChunks、maxAsyncRequests、maxInitialRequests都属于匹配条件。
- 命名 配置项name默认为true,意味着SplitChunks可以根据CacheGroups和作用范围自动为新生成的chunk命名,并且以automaticNameDelimiter分割。
- CacheGroups 可以理解为分离chunks时的规则。
默认配置
代码语言:javascript复制module.exports = {
...
splitChunks: {
chunks: 'async',
miSize: {
javascript: 30000,
style: 50000,
},
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
test: /[\/]node_modules[\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
}
小结
本篇了解了两种代码分片方式:
- 入口规划
- SplitChunks
而借助这些方法,我们可以有效的缩小资源体积,更好的利用缓存,从而给用户更有好的体验度。
下一篇介绍生产环境优化中的一些配置,如环境配置封装、sourceMap等。