BundleMon:在 CI 里给前端包体积设硬红线
阅读时间: 大约 10 分钟
BundleMon:在 CI 里给前端包体积设硬红线

BundleMon 是一个面向前端构建产物的体积监控工具(npm 包 bundlemon,官方提供免费托管服务与自托管选项)。它的核心主张很简单:包体积失控不是一次性事故,而是持续迭代中缺少管控的结果;与其靠”发版前再优化”的妥协,不如在每次提交时比对基线分支,当单文件绝对大小或相对涨幅突破阈值就让构建直接失败。本文基于官方 README,解析其配置模型、CI 集成与免费版限制。
一、背景:为什么”警告”拦不住体积膨胀
前端项目迭代中,新增依赖、路由懒拆失败、重复打包都会让 chunk 体积缓慢爬升。常见做法是在 CI 里打印一行体积日志或发一条告警,但告警不阻断合并,团队 deadline 紧张时几乎一定会被忽略。BundleMon 选择的机制是失败即拦截(fail build):超限不是”提个醒”,而是让这次提交合不进去。官方点评也认为,构建失败比警告通知更能杜绝”先合并再优化”。
二、配置模型:maxSize + maxPercentIncrease
安装后在 package.json 的 bundlemon 字段(也支持 .bundlemonrc、.bundlemonrc.json、bundlemon.config.js 等 cosmiconfig 格式)声明:
{
"bundlemon": {
"baseDir": "./build",
"files": [
{ "path": "index.html", "maxSize": "2kb", "maxPercentIncrease": 5 },
{ "path": "bundle.<hash>.js", "maxSize": "10kb" },
{ "path": "assets/**/*.{png,svg}" }
]
}
}两条红线各自独立:
maxSize:文件绝对大小上限,超过即失败;maxPercentIncrease:相对基线分支允许的涨幅百分比,超过即失败。
其他关键配置项:
| 配置 | 作用 |
|---|---|
groups | 把匹配模式的文件体积求和,对总和应用规则 |
defaultCompression | 计算体积前先压缩,none/gzip/brotli,默认 gzip |
reportOutput | 结果输出渠道,含 github、verbose 等 |
subProject / BUNDLEMON_SUB_PROJECT | monorepo 多子项目共用一个 project id |
includeCommitMessage | 把提交信息一并存档 |
pathLabels | 用 <hash> 等占位符抹平带哈希文件名的每次变化 |
pathLabels 是工程细节里的关键:带内容哈希的文件名(home.b72f15a3.chunk.js)每次构建都变,直接按路径追踪会把哈希变化误判为新文件。配置里用 *.<hash>.chunk.js 这类模式把哈希位替换成常量标签,BundleMon 才能跨版本追踪同一路由 chunk。
三、GitHub 集成:Check run、提交状态、PR 评论
官方 GitHub 集成提供三种通知形态,都可独立开关(true | false | "always" | "on-failure" | "pr-only" | "off"):

- Check run:在 PR 的 Checks 标签页给出结构化结果;
- Commit status:直接打在提交上的通过/失败状态;
- PR 评论:在 PR 里发一条逐文件差异表。

PR 评论表里每个文件一行:状态(通过/失败)、变化类型(NO CHANGE / UPDATE)、路径、当前体积(增量与百分比)、Max Size 上限;任何一项超限,Final result 即为失败。README 示例里 css/main.(hash).css 涨到 357.22KB(+74.36KB / +26.29%)超过 300KB 上限,整表最终判负。
安装途径是官方 GitHub App;非 GitHub Actions 环境需要提供一个无需 scope 的 BUNDLEMON_GITHUB_TOKEN(官方明确说明服务端不保存该 token,仅用于校验发起用户)。工具支持来自 fork 的 PR,官方另附 GitHub Actions 与 CodeFresh 的分步指南。CI 方面原生支持 GitHub Actions、Travis、CodeFresh;CircleCI 需手动设置 CI_TARGET_BRANCH。
四、历史报告与自托管
接入托管项目后,每次提交的体积记录存入服务端,历史报告页面可按分支、分辨率(天)回溯,悬停单次提交查看各文件体积,形成一条体积治理曲线。除免费托管外,README 提供自托管文档,适合不想把构建产物元数据交给第三方的团队。
五、局限与口径(免费版保留策略,官方原文)
官方在”free hosted service”一节明确列出免费托管的保留限制:
- PR 创建的记录 14 天后删除;
- 无活动(无新提交)分支的记录 180 天后删除;
- 60 天后每个文件只保留每天最新一条记录。
官方同时声明”随着项目增多,未来可能增加更多限制”。这意味着免费版适合做 PR 阶段的即时拦截与短期趋势观察,不适合作为长期体积档案;需要多年历史曲线或合规留存的团队应走自托管。
其他口径注意:
- 默认 gzip 计算:
defaultCompression默认 gzip,比较的是压缩后体积,未压缩源码体积与传输体积不要混淆; - 阈值是人为约定:maxSize 与涨幅百分比没有客观最优值,需要团队按自身性能预算协商,工具只负责强制执行;
- 只管大小不管内容:BundleMon 不分析依赖重复、treeshaking 失败或未使用代码,它是守门员,不是优化器;
- 基线依赖:相对涨幅需要正确的目标分支上下文,fork PR 与特殊 CI 环境要手动补
CI_TARGET_BRANCH等变量。
六、适用与不适用
适合:有明确性能预算、希望把体积红线写进合并流程的团队;monorepo 多子项目分别记账;需要在 PR 里直接看到逐 chunk 增量、阻止”先合再说”的开源与商业前端项目。
不适合:只想要一次性体积分析报告、不打算设阈值拦截的场景;需要长期历史档案却不愿自托管、也不接受免费版保留策略的合规场景;把它当作依赖瘦身/包分析工具使用的预期。
七、它意味着什么
BundleMon 的工程价值在于把”包体积治理”从口头约定变成 CI 里不可绕过的硬约束:阈值提前谈好,机器强制执行,超限即红。它本身不优化任何字节,但把优化的决策点左移到了每次提交,这正是持续集成时代防止技术债缓慢堆积的典型手法。