- 可观测性
【免费下载链接】sentry-javascript
Official Sentry SDKs for JavaScript
导读
本文基于 sentry-javascript 仓库的维护技能文档(.agents/skills/bump-size-limit/SKILL.md),系统讲解当 size-limit GitHub Action 检查失败时,如何正确完成"全量构建 → JSON 模式测量 → 定位失败场景 → 计算新阈值 → 更新.size-limit.js→ 复验"的完整流程。读完本文,你将掌握 size-limit 输出的 JSON 字段含义、KB 与 KiB 两种单位的换算规则,以及仓库内手动调阈值与每周自动 bump 两条并行的维护路径。
背景:sentry-javascript 如何用 size-limit 守护包体积
sentry-javascript 是一个包含 Browser、Node、React、Vue、Svelte、Next.js、Cloudflare 等数十个 SDK 包的 monorepo。为了守住"引入 SDK 后用户包体积增长可控"这条红线,仓库在根目录维护了一个 .size-limit.js 配置文件,由 size-limit 工具在 CI 中执行测量。
触发检查的脚本定义在根目录 package.json:
"test:size-limit": "yarn size-limit --json",当 CI 中的 size-limit 检查失败时,本质含义是:某个或多个 bundle 场景的实际体积(size)超过了.size-limit.js中为该场景配置的字节阈值(sizeLimit)。这通常发生在新增功能、引入新依赖或重构后产物体积自然增长时。本文的 Skill 文档给出了处理该问题的标准操作流程。
完整手动工作流:六步完成阈值调整
Skill 文档规定了严格的操作顺序,核心原则是"只调整真正失败的场景,绝不触碰通过的场景"。以下六个步骤完整继承自该文档,并补充了仓库内的实现佐证。
Step 1:全量构建(含 CDN bundles)
yarn buildsize-limit 测量的是实际编译后的产物,因此必须先完成全量构建。该命令在 package.json 中被定义为:
"build": "node ./scripts/verify-packages-versions.js && nx run-many -t build:transpile build:types build:bundle",注意:构建需要几分钟时间,且必须保证packages/browser/build/bundles/下的 CDN bundle 是最新的——dev build(如yarn build:dev)不足以支撑 size-limit 测量,因为 CDN 场景直接指向这些 bundle 文件。
Step 2:以 JSON 模式运行体积检查
yarn test:size-limit对应 package.json 中的yarn size-limit --json。--json标志让 size-limit 输出结构化 JSON 而非人类可读文本,便于脚本解析和筛选。
Step 3:从 JSON 输出中识别失败场景
JSON 输出是一个对象数组,每个对象包含四个核心字段(Skill 文档原文定义):
| 字段 | 含义 |
|---|---|
name | 场景标签,如@sentry/browser、CDN Bundle (incl. Tracing) |
passed | 布尔值,是否在配置的阈值内 |
size | 实际体积(字节) |
sizeLimit | 配置的体积上限(字节) |
用过滤器筛选出"passed": false的条目——这些是唯一需要调整阈值的场景。
Step 4:计算新阈值(保守向上取整启发式)
对于每个失败场景,将实际体积向上取整到下一个完整 KB。Skill 文档特别强调:在本仓库的语境下,1 KB = 1000 字节(十进制),这与 size-limit 解析.size-limit.js中'130 KB'这类字符串的方式一致。
文档示例:实际体积为129,127字节时,新阈值为130 KB(即 130,000 字节)。
这个启发式刻意保持保守——只给出恰好足够的余量,避免无谓地虚高所有场景的阈值。向下取整或保留小数是不允许的,因为它无法保证给出完整余量。
Step 5:更新.size-limit.js
打开仓库根目录的 .size-limit.js,定位到每个失败场景的limit字段并更新。limit是字符串,格式形如'130 KB':
{ name: '@sentry/browser', path: 'packages/browser/build/npm/esm/prod/index.js', import: createImport('init'), gzip: true, limit: '34 KB', // ← 修改这里 disablePlugins: ['@size-limit/esbuild'], },只修改实际失败的场景。通过的场景保持原样,避免人为扩大整个仓库的体积基线。
Step 6:复验修复
yarn test:size-limit重新运行检查确认全部通过。如果仍有场景失败(例如取整边界问题),只针对该具体场景再增加 1 KB,然后再次运行。反复执行直到绿灯。
深入解析.size-limit.js:结构、字段与单位
对 .size-limit.js(共 531 行)的源码分析,可以确认该文件由一组场景对象组成,每个对象除了name、path、limit外,还大量使用以下字段:
import:指定测量时从入口导入的符号,文件底部 createImport 辅助函数将参数拼接为{ init, browserTracingIntegration }形式的解构导入;gzip/brotli:是否启用 gzip/brotli 压缩测量。CDN 压缩场景默认gzip: true,而非压缩场景显式声明gzip: false, brotli: false(见 非压缩 CDN 场景);ignore:从 bundle 中排除的模块,如 Node SDK 场景忽略builtinModules与node:前缀的内置模块(.size-limit.js),React 场景忽略react/jsx-runtime;disablePlugins:禁用@size-limit/esbuild或@size-limit/webpack,例如 Cloudflare 场景因使用 esbuild 测量而禁用 webpack 插件(.size-limit.js);modifyWebpackConfig/modifyEsbuildConfig:函数形式的自定义构建配置,用于模拟真实使用场景。例如 browser treeshaking 场景 通过webpack.DefinePlugin关闭调试标志和 Replay Worker,@sentry/node/import场景则强制保留副作用以真实测量 Node 运行时加载量(.size-limit.js);webpack: false:对 Cloudflare 场景直接关闭 webpack 链路,改用modifyEsbuildConfig对齐wrangler deploy的构建参数(.size-limit.js)。
单位问题需要特别留意:该文件绝大多数场景使用十进制KB(1 KB = 1000 字节),但 Cloudflare 的两个场景使用的是二进制KiB(.size-limit.js 中的limit: '205 KiB'),这是为了匹配wrangler deploy的输出口径。手动调整时必须确认目标场景的单位,不要跨单位照搬数值。
场景覆盖范围从文件结构看可归纳为几大类:Browser SDK 各功能组合(Tracing / Replay / Feedback / Metrics / Logs 的排列组合)、React/Vue/Svelte SDK、Browser CDN bundles(压缩与非压缩两套)、Next.js 与 SvelteKit 客户端入口、@sentry/core子路径入口、Node SDK 多个变体、AWS Serverless、Cloudflare Worker SDK。
仓库内的自动化补充:自动 bump 脚本
除了 Skill 文档描述的手动流程,仓库还提供了自动化脚本 scripts/bump-size-limits.mjs,可以作为理解阈值计算规则的对照实现。该脚本的启发式与手动流程略有不同:它计算ceil((实际体积 + 5000) / 1000) * 1000,即先加 5 KB 安全余量再向上取整到整 KB(见 computeNewLimit,常量定义于 第 24-26 行:HEADROOM_BYTES = 5000、BYTES_PER_KB = 1000、BYTES_PER_KIB = 1024)。
该脚本有几个值得借鉴的实现细节:
- 通过
yarn --silent size-limit --json以无 shell 方式执行并捕获 stdout(main 入口),即使 size-limit 因超限返回非零退出码,也保留 JSON 输出继续解析; - 绝不
require().size-limit.js,而是以纯文本方式读取并用正则按name:精确匹配后重写limit:行(rewriteSizeLimitFile),因为该文件内含用户自定义的 webpack/esbuild 配置函数,不应被脚本执行; - 通过临时文件 + rename 实现原子写入(第 236-240 行);
- 单位换算后显示值未变化时跳过编辑,避免 KiB 取整造成的无效变更(第 213-217 行)。
该脚本由每周自动 workflow .github/workflows/bump-size-limits.yml 驱动,提交信息为chore(size-limit): auto-bump weekly drift,以bot/bump-size-limits分支发起 PR。手动 bump 与自动 bump 是两条互补路径:手动流程适合 PR 开发过程中的即时修复,自动脚本负责每周消除累积的体积漂移。
CI 中的 size-limit 检查链路
了解检查如何接入 CI,有助于理解"为何失败"以及"为何必须这样修"。仓库的 size-limit 检查集成在 .github/workflows/build.yml 的 "Check bundle sizes" 步骤中:
- name: Check bundle sizes uses: ./dev-packages/size-limit-gh-action with: github_token: ${{ secrets.GITHUB_TOKEN }} # Only run comparison against develop if this is a PR comparison_branch: ${{ (github.event_name == 'pull_request' && github.base_ref) || ''}}该 action 的实现位于 dev-packages/size-limit-gh-action/index.mjs,核心行为包括:
- 执行
yarn run --silent size-limit --json获取当前分支测量结果(execSizeLimit); - 通过 SizeLimitFormatter.parseResults 将 JSON 解析为
{ name, size, sizeLimit, passed }结构——这正是 Skill 文档 Step 3 所依赖的字段来源; - 若配置了
comparison_branch(PR 场景下为 develop),则拉取对比分支的测量 artifact,按 hasSizeChanges 计算相对阈值内是否存在变化,决定是否在 PR 上发布/更新 Markdown 对比表格; - 若 size-limit 进程返回非零状态,则以
setFailed('Size limit has been exceeded.')标记检查失败(index.mjs 第 183-203 行),并在日志中输出超限场景列表Exceeded size-limits:。
Action 的输入参数定义在 dev-packages/size-limit-gh-action/action.yml:github_token(必填)、comparison_branch(可选,指定对比分支)、threshold(默认0.0125,即体积相对变化超过 1.25% 才发布评论)。
这套链路回答了 Skill 文档的隐含问题:当 CI 报错时,报错信息中的Exceeded size-limits列表对应的就是.size-limit.js中需要 bump 的场景,与手动流程 Step 3 的筛选结果一致。
边界情况与最佳实践
综合 Skill 文档与仓库实现,实践中有几点值得注意:
- 取整边界:
129,900字节这类恰好接近整 KB 上限的数值,按向上取整规则会得到130 KB,仅给出 100 字节余量。复验时若仍失败(如测量存在微小波动),按 Skill 文档规定对该场景单独 +1 KB 后重跑,不要批量上调其他场景。 - KB 与 KiB 混用:绝大多数场景用十进制
KB(1000 进制),Cloudflare 场景用KiB(1024 进制)。手动计算时以场景现有单位为准,自动脚本 bytesToDisplay 正是按cur.unit动态选择除数。 - 改后必须复验:
.size-limit.js中的modifyWebpackConfig/modifyEsbuildConfig会影响测量结果,修改limit后重新运行yarn test:size-limit是唯一可靠的验证方式。 - 保持最小改动:只 bump 失败场景,避免通过阈值膨胀掩盖未来的体积回归;这既是 Skill 文档的硬性规定,也符合自动脚本"显示值未变化则跳过"的克制策略。
小结
当 sentry-javascript 的 size-limit CI 检查失败时,标准处理流程可浓缩为:yarn build全量构建 →yarn test:size-limit以 JSON 模式测量 → 筛选passed: false的场景 → 按 1 KB = 1000 字节向上取整计算新阈值 → 只更新.size-limit.js中失败场景的limit→ 重跑复验,必要时单场景 +1 KB 迭代。若希望了解仓库如何自动化这一过程,可进一步阅读 scripts/bump-size-limits.mjs(手动流程的脚本化对照)与 dev-packages/size-limit-gh-action(CI 检查的实现源头)。
- 可观测性
【免费下载链接】sentry-javascript
Official Sentry SDKs for JavaScript
相关推荐
Effect 仓库 Bundle Size 开发工作流实战:用 Rollup + gzip 测量、对比与分析包体积
Effect 仓库 Bundle Size 开发工作流实战:用 Rollup + gzip 测量、对比与分析包体积 本文面向在 .repos/effect sm
AI Agent代码智能体后端前端移动开发桌面应用tmux-rs快速入门:如何在5分钟内安装和运行Rust版tmux 🚀
tmux rs快速入门:如何在5分钟内安装和运行Rust版tmux 🚀 想要体验用Rust语言重新实现的tmux终端复用器吗?tmux rs是一个激动人心的开
Size Limit 性能基准测试:如何建立科学的评估体系
Size Limit 性能基准测试:如何建立科学的评估体系 在现代前端开发中,JavaScript 应用和库的体积控制已成为保证用户体验的关键因素。 Size
开发工具前端测试
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考