记录一次 Webpack 优化
开篇
本次优化主要做的是 Webpack 打包资源体积大小的优化,目的是为了解决单页面应用首页加载白屏时间过长问题。
下面会根据分析优化的步骤一一记录分享。
分析 package.json 依赖
- 清除无用依赖(比如,项目中 import 导入了有个模块,但是没有引用 - 开发者的代码不规范操作);
- 对包进行分类:
-
只在开发环境所使用的依赖(babel、webpack)安装在
devDependencies
之下; -
需要进行打包部署的程序运行代码(react、antd)安装在
dependencies
之下; -
这个规范在一个
npm 线上包
的开发尤其重要。
-
配置 babel-plugin-import
现在的打包工具(Webpack)和组件库(Antd)都已支持 tree-shaking
的优化,无需再配置按需引入,但如果不支持 tree-shaking
,则还是需要配置 babel-plugin-import
来优化 UI 组件库的打包体积。
- 安装:
npm install babel-plugin-import -D
- 使用(BabelV6):
// .babelrc
{
...
plugins: [
...
[
"import", [
{ "libraryName": "antd", "libraryDirectory": "lib", style: "css" },
{ "libraryName": "antd-mobile", "libraryDirectory": "lib", style: "css" },
]
]
]
}
如果使用的是 BabelV7 版本,配置多个按需加载模块时,可以配置多个 import
实例:
// .babelrc
"plugins": [
["import", { "libraryName": "antd", "libraryDirectory": "lib"}, "antd"],
["import", { "libraryName": "antd-mobile", "libraryDirectory": "lib"}, "antd-mobile"]
]
优化 moment.js
如果项目中有用到 moment.js 这个库,它默认会引入所有的多语种资源文件,我们可以进行配置,只引入我们需要的语种资源:
// webpack.config.js
const webpack = require('webpack');
module.exports = {
...
plugins: [
// 只加载 `moment/locale/zh-cn.js` 和 `moment/locale/en-xx.js`
new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn|en/),
]
}
externals 外部扩展
对于项目中使用到的一些依赖,我们不希望在打包的时候将它们打包进去,而是在 html 模板中使用 script 标签对其引入,我们可以在 webpack 配置中对相关模块进行“忽略”。
// webpack.config.js
module.export = {
// ...
externals: {
jquery: 'jQuery',
},
}
在 html 模板中引入 cdn 资源:
<body>
<div id="root"></div>
// 资源将 jQuery 绑定到了 window 全局上
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
</body>
vendor 抽离(分包)
将一个体积较大的打包资源文件,拆分为多个小资源文件进行引入,借助于浏览器同时并发加载多个资源的特性来优化资源加载时长。
// webpack.config.js
module.exports = {
...
output: {
path: path.resolve(__dirname, 'build'),
filename: 'scripts/js/[name].js', // 入口文件的命名
chunkFilename: "scripts/js/[name].js?v=[chunkhash:8]", // 分包的命名
},
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
common: {
chunks: "all",
minChunks: 2,
name: 'chunk-common',
enforce: true,
priority: 5
},
vendor: {
name: 'chunk-vendors',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial'
},
antd: {
name: 'chunk-antd',
priority: 20,
test: /[\\/]node_modules[\\/]_?antd(.*)/
},
}
}
},
}
打包分析工具
上面所做的都是已知可以优化的项,我们可以借助于打包资源分析工具,它提供了一个每个模块的体积大小可视化展示,可以针对某个依赖模块进行优化。
- 安装:
npm install webpack-bundle-analyzer -D
- webpack 配置:
// webpack.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
...
plugins: [
...
new BundleAnalyzerPlugin(),
]
}
- 启动:
npm run build(打包)
or
npm start(启动 devServer)
最后
经过这轮优化,体会更深的该是开发者们对自身开发的要求,比如尽量避免出现以下类似情况:
- 掌握打包工具的正确使用方式。比如项目中配置多个
babel-plugim-import
的方式不对,导致没有按需引入没有生效;(可以查看包的 npm 相关文档的使用介绍) - 避免为实现某一个小功能,而引入了一个非常大的依赖包,在做功能实现时,一定要深思熟虑,选择最优方案。
转载自:https://juejin.cn/post/7056324070186418184