Skip to content

核心选项与视图

基于 webpack-contrib/webpack-bundle-analyzer 官方 README(master 分支)+ viewer.js 源码编写,对照稳定版 5.3.0

速查

  • 图表仅 Treemap 一种——sunburst / network 是 bundle-stats / Statoscope 竞品特性
  • 四种启动模式:server(默认,HTTP)/ static(HTML)/ json(JSON)/ disabled(仅 stats)
  • 四档体积:stat(输入)/ parsed(输出,默认)/ gzip / brotli;生产评估看 gzip / brotli
  • defaultSizes:图表初始显示哪一档compressionAlgorithm:算压缩档时用哪种压缩算法——两件事别混
  • CI 配置三件套:analyzerMode: 'static' + analyzerPort: 'auto' + openAnalyzer: false
  • excludeAssets 三种 pattern:String(转 RegExp)/ RegExp / (assetName) => boolean;多 pattern 任一匹配即排除
  • UI 交互:左侧 sidebar(点 > 展开)勾选 chunk;右键 / Ctrl+click chunk 弹 Context Menu(Hide chunk / Hide all other chunks / Show all chunks)
  • 防源码泄漏:generateStatsFile: true + statsOptions: { source: false }(stats JSON 默认含模块源码)
  • Vite / Rollup 项目不能用本工具——换 rollup-plugin-visualizernpx vite-bundle-visualizer
  • 反模式:CI 跑 server 模式、dev-server 下跑 CLI、把 parsed 当真实传输体积、对 Vite 项目硬塞

启动模式:server / static / json / disabled

四种模式由 analyzerMode 选项决定,对应「报告以什么形态产出」。

server(默认)—— 本地分析

js
new BundleAnalyzerPlugin({
  analyzerMode: 'server',     // 默认
  analyzerHost: '127.0.0.1',  // 默认
  analyzerPort: 8888,         // 默认;可设 'auto' 让 OS 分配
  openAnalyzer: true,         // 默认自动开浏览器
})

启动后控制台打印 Webpack Bundle Analyzer is started at http://127.0.0.1:8888,HTTP server 不退出——适合本地一次性分析,严禁在 CI 跑

analyzerPort: 'auto' 让 OS 分配空闲端口,避免并行 build、容器化、多项目共享机器时 EADDRINUSE。

static —— CI / 团队共享

js
new BundleAnalyzerPlugin({
  analyzerMode: 'static',
  reportFilename: 'report.html',  // 默认;可为函数 () => string
  reportTitle: 'Bundle Report',   // 默认;可为函数
  openAnalyzer: false,            // CI 不开浏览器
})

生成单 HTML 文件(无外部依赖,离线可看),归档为 CI 产物或 commit 进仓库都方便。这是 CI 场景的标准选择。

json —— 程序化处理

js
new BundleAnalyzerPlugin({
  analyzerMode: 'json',
  reportFilename: 'report.json',
})

输出 JSON 报告,供下游脚本 / 工具消费(如自建体积看板、跨构建 diff)。

disabled —— 只要 stats

js
new BundleAnalyzerPlugin({
  analyzerMode: 'disabled',
  generateStatsFile: true,    // 配合此项才有意义
  statsFilename: 'stats.json',
})

不启动 server、不出报告,仅生成 webpack stats JSON,给 bundle-stats / Statoscope 等下游工具二次分析。

四档体积:stat / parsed / gzip / brotli

报告顶部有切换按钮(默认 parsed),切换后所有矩形重画。各档含义:

档位含义来源典型用途
stat输入大小,变换前Webpack stats 对象看模块「自身体量」,判断 Tree-shaking 空间
parsed(默认)输出大小,压缩后(Terser / Uglify 处理)读磁盘 bundle看「写进 bundle 多少」,CI 报告默认
gzip对 parsed gzip 后算出看「用户实际下载多少」——定性能预算必看
brotli对 parsed brotli 后算出(compressionAlgorithm: brotli)同上,brotli 比 gzip 多省 15–20%

两个易混选项

选项作用取值
defaultSizes报告初始显示哪一档stat / parsed / gzip
compressionAlgorithm算压缩档时用哪种压缩算法gzip(默认)/ brotli / zstd(需 Node 22.15.0+)

别搞混:defaultSizes: 'gzip' 是「打开报告就显示 gzip 档」;compressionAlgorithm: 'brotli' 是「压缩档按 brotli 算」。两个维度独立。

stat vs parsed 判断优化方向

对照结论
stat 远大于 parsed压缩器效果好(注释 / 空白多被吃掉),无需 Tree-shaking
stat 与 parsed 接近模块本身冗余(死代码、未使用的导出),应做 Tree-shaking / 代码分割

仅 Treemap 一种视图(重点澄清)

Webpack Bundle Analyzer 的可视化图表只有 Treemap 一种——矩形树图,矩形面积 = 模块体积。

社区博客常把它和竞品混说成「treemap / sunburst / network 三种视图」——这是错的,也是高频考点

  • sunburst(旭日图):bundle-stats、Statoscope 等竞品支持,本工具不支持
  • network(网络图):同上,是竞品特性
  • treemap(矩形树图):本工具唯一支持的图表

找不到 sunburst / network 切换按钮是正常的——要换视图请换工具。

Treemap 交互能力

操作行为
鼠标悬停显示模块名、stat/parsed/gzip 三档体积、路径
点击矩形钻入子模块(zoom in)
左侧 sidebar(点 > 展开)勾选 / 取消 chunk
右键 / Ctrl+click chunkContext Menu:Hide chunk / Hide all other chunks / Show all chunks
顶部切档按钮切 stat / parsed / gzip

Context Menu 的 Hide chunk 不是「不打包」,只影响报告展示——excludeAssets 同理,只过滤展示,体积优化仍要在 webpack config 里处理。

excludeAssets:过滤噪声

excludeAssets 三种 pattern:

js
new BundleAnalyzerPlugin({
  excludeAssets: [
    /\.map$/,           // RegExp:排除 sourcemap
    'LICENSE',          // String:转 RegExp,匹配资产名含 LICENSE
    (name) => name.endsWith('.woff2'),  // 函数:返回 true 即排除
  ],
})

多 pattern 是「任一匹配即排除」(OR 语义)。常用于过滤 sourcemap / 字体 / 第三方 LICENSE,让 treemap 聚焦在真正需要审查的 JS chunk 上。

generateStatsFile:保留原始数据

js
new BundleAnalyzerPlugin({
  generateStatsFile: true,
  statsFilename: 'stats.json',
  statsOptions: { source: false },  // 关键:不写源码
})
配置作用
generateStatsFile: true额外输出 webpack stats JSON
statsFilename文件名,默认 stats.json
statsOptions透传给 stats.toJson()
statsOptions: { source: false }不写模块源码——CI 产物上传时防泄漏

stats JSON 默认会写入模块源码;CI 共享 / 上传产物时务必加 { source: false },否则可能泄漏私有代码。

与 Vite / Rollup 的关系

项目能用本工具吗?推荐替代
Webpack 项目(任何版本)可以本工具
Vite 项目不能——Vite 用 Rollup,无 webpack stats JSONrollup-plugin-visualizer(集成进 vite.config.ts plugins)
Vite 项目(零配置)不能npx vite-bundle-visualizer
纯 Rollup 项目不能rollup-plugin-visualizer

替代品产物都是 treemap,UI 体验与本工具对齐。Vite 项目别尝试 npm i webpack-bundle-analyzer——会有 webpack 依赖、stats JSON 根本不存在。

反模式与陷阱

反模式后果正确做法
CI 跑 server 模式HTTP server 不退出,pipeline 卡死static 模式
并行 build 用固定 8888 端口EADDRINUSE 报错analyzerPort: 'auto'
webpack-dev-server 下跑 CLINo such file 报错,退化为只有 stat size用 Plugin 模式(拿内存产物)
拿默认 parsed 当真实传输体积业务结论偏差(实际是 gzip 1/3)切到 gzip / brotli
混淆 defaultSizes / compressionAlgorithm报告档位与压缩算法乱套记住:defaultSizes 初始档 / compressionAlgorithm 算法
上传 stats JSON 不去源码私有代码泄漏statsOptions: { source: false }
excludeAssets 能减少 bundle 体积只过滤展示,bundle 没变体积优化在 webpack config 里处理
对 Vite 项目用本工具装不上 / 拿不到 statsrollup-plugin-visualizer
误以为有 sunburst / network 视图找不到切换按钮那是竞品特性;本工具仅 treemap

最佳实践清单

js
// webpack.analyze.js —— 单独的分析配置,按需启用
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const base = require('./webpack.config');

module.exports = {
  ...base,
  plugins: [
    ...base.plugins,
    new BundleAnalyzerPlugin({
      analyzerMode: 'static',        // CI 友好
      reportFilename: 'report.html',
      openAnalyzer: false,           // CI / 服务器不开浏览器
      analyzerPort: 'auto',          // 防端口冲突(static 模式不监听,写习惯防切换)
      defaultSizes: 'gzip',          // 生产评估默认看 gzip
      excludeAssets: [/\.map$/, /LICENSE/],
      generateStatsFile: true,       // 给下游工具
      statsOptions: { source: false }, // 防源码泄漏
      logLevel: 'warn',
    }),
  ],
};
bash
ANALYZE=1 webpack --config webpack.analyze.js

下一步

  • 入门:安装、最小用法、四种启动模式速览
  • 参考:完整选项表、CLI flag 表、版本与链接