如何分析 Webpack 打包后的体积和依赖关系?
在 Webpack 中分析打包后的体积和依赖关系,最有效且常用的方法是使用可视化分析工具和生成 Stats JSON 文件。
以下是具体的实施方法和步骤,从最推荐的方案到高级技巧:
方法一:使用 webpack-bundle-analyzer(最推荐 ⭐️⭐️⭐️⭐️⭐️)
这是 Webpack 社区最流行、最直观的可视化分析插件。它会将打包后的体积生成为一个交互式的树状图(Treemap)。
1. 安装插件
bash
npm install -D webpack-bundle-analyzer
# 或
yarn add -D webpack-bundle-analyzer
2. 配置 webpack.config.js
javascript
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
// ... 其他配置
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: 'server', // 启动一个 HTTP 服务器展示报告
analyzerPort: 8888, // 端口号
openAnalyzer: true, // 构建完成后自动打开浏览器
generateStatsFile: false, // 是否生成 stats.json 文件
defaultSizes: 'parsed', // 默认显示的文件大小:stat, parsed, gzipped
})
]
};
3. 运行打包
运行你的构建命令(如 npm run build),打包完成后会自动打开 http://127.0.0.1:8888。
4. 图表解读指南:
- 模块大小区别:
- Stat size:源码未压缩前的大小。
- Parsed size:打包压缩(如 Terser)后的 JS 文件大小(最贴近浏览器实际加载大小)。
- Gzip size:开启 Gzip 压缩后传输的大小(最贴近网络传输大小)。
- 寻找优化点:
- 大块头(Big Blocks):查找体积极大的第三方库(如
lodash,moment.js)。 - 重复包(Duplicates):检查是否有同一个库的不同版本被重复打包。
- 不必要的代码:检查是否有本不需要在前端引入的库(如
node_modules中的后端工具)。
- 大块头(Big Blocks):查找体积极大的第三方库(如
方法二:生成 stats.json + 在线可视化工具
如果你不想在构建流程中增加插件,可以导出 Webpack 的原生分析数据文件,然后上传到在线工具分析。
1. 生成 stats.json
修改你的 package.json 中的构建脚本,添加 --json 参数:
json
"scripts": {
"build:stats": "webpack --profile --json > stats.json"
}
注:如果你使用的是 vue-cli 或 create-react-app,也有对应的命令行参数导出 stats。
2. 将 stats.json 上传到在线分析平台:
- 官方推荐:Webpack Analyze
- 显示依赖图谱、模块互相引用的原因、提示隐患(如重复引用的模块)。
- Webpack Chart
- 饼图展示,非常清晰地看清每个模块占总体积的百分比。
- Bundle Buddy
- 专门用来查找 跨 Chunk 的重复代码,非常适合做 Code Splitting 优化。
方法三:使用 source-map-explorer(源码级分析)
如果你想知道打出来的 .js 文件里,具体是哪一行代码/哪个组件占了多少体积,可以通过 Source Map 反向分析。
1. 确保生产环境生成 Source Map
在 webpack.config.js 中开启:
javascript
module.exports = {
devtool: 'source-map', // 必须生成 .map 文件
}
2. 安装并运行 source-map-explorer
bash
npm install -g source-map-explorer
# 运行分析(传入打包后的 js 文件和对应的 map 文件)
source-map-explorer dist/static/js/main.xxxx.js
它会在浏览器打开一个类似 webpack-bundle-analyzer 的界面,但粒度细化到了源码文件中的每个函数和变量。
辅助分析工具(预判与排查)
1. 在 VS Code 中实时查看导入包的大小:Import Cost 插件
在 VS Code 插件市场搜索并安装 Import Cost。
当你在代码中写入 import _ from 'lodash' 时,它会在行尾实时显示这个包的大小。
2. 安装前预估包体积:Bundlephobia
在引入一个新的 npm 包之前,访问 bundlephobia.com ,输入包名即可查询:
- 该包的体积大小(Minified & Gzipped)。
- 下载所需时间。
- 是否支持 Tree Shaking(按需引入)。
总结:常见的体积优化切入点
通过上述工具分析后,通常可以采取以下手段进行优化:
- 替换大体积库:
- 将
moment替换为dayjs或date-fns(体积缩减 90%)。 - 将全量
lodash替换为lodash-es或单独引入函数import cloneDeep from 'lodash/cloneDeep'。
- 将
- 路由懒加载 / 动态导入:使用
import()语法分割代码块(Code Splitting)。 - 提取公共代码:配置
optimization.splitChunks提取公共第三方库(如 React/Vue 全家桶)。 - 开启 Tree Shaking:确保使用 ES Module 语法(
import/export),并在package.json中配置"sideEffects": false。 - CDN 外链:将 Vue/React 等基础库通过
externals配置排除,改用 CDN 加载。