8.1 biome ci:为什么不是 biome check
两者主要差异:
| biome check | biome ci | |
|---|---|---|
| 意图 | 本地开发 | CI 流水线 |
| 支持 --write | ✅ | ❌(CI 不该改代码) |
| 格式化差异 | 报告即可 | 直接算 error |
| reporter 默认 | 人类可读 | GitHub Actions 格式 |
| 并发 | 自动 | --max-diagnostics 防日志爆炸 |
简言之:CI 里就是 biome ci .,别用 check。
8.2 GitHub Actions 范例
# .github/workflows/lint.yml
name: Lint
on:
push:
branches: [main]
pull_request:
jobs:
biome:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 } # --changed 需要历史
- uses: biomejs/setup-biome@v2
with:
version: latest
- run: biome ci .
# PR 里 biome 会用 GitHub annotation 格式,
# 每个错误都显示在 PR 的 Files changed 标签页对应行
如果已有 @biomejs/biome devDep,直接 pnpm install --frozen-lockfile && pnpm biome ci . 即可——省掉额外 action,版本与代码完全一致。
8.3 只 lint 改动文件(超大 monorepo)
- name: Lint changed only
run: biome ci --changed --since=origin/main .
百万行仓库可以把 lint 时间从 8s 压到 0.6s。注意 fetch-depth: 0 必须,否则 git 找不到 origin/main。
8.4 Reporter 格式
biome ci --reporter=github # GitHub Actions annotation
biome ci --reporter=gitlab # GitLab CI
biome ci --reporter=junit # JUnit XML,Jenkins/CircleCI
biome ci --reporter=json # 机器处理
biome ci --reporter=summary # 人类简报
把 --reporter=junit 的输出保存成 artifact 并上传,可在 Jenkins、CircleCI 里看到每个违规项作为"测试失败"展示。
8.5 GitLab CI 范例
# .gitlab-ci.yml
lint:
image: node:20-alpine
script:
- corepack enable
- pnpm install --frozen-lockfile
- pnpm biome ci --reporter=gitlab .
artifacts:
reports:
codequality: gl-code-quality-report.json
8.6 缓存加速
Biome 内置基于文件哈希的缓存,位置 ./node_modules/.cache/biome/。在 GitHub Actions 里:
- uses: actions/cache@v4
with:
path: node_modules/.cache/biome
key: biome-${{ hashFiles('biome.json') }}-${{ hashFiles('**/*.ts','**/*.tsx') }}
restore-keys: |
biome-${{ hashFiles('biome.json') }}-
第二次同一分支跑 CI 时,未变更文件直接读缓存;体感差别:6s → 0.4s。
8.7 pre-commit / husky
# .husky/pre-commit
#!/usr/bin/env sh
npx biome check --staged --write --no-errors-on-unmatched \
&& git update-index --again
git update-index --again:Biome 改过的文件自动加回 index,避免"改完却没提交"。
8.8 pre-push:最后一道栅栏
# .husky/pre-push
npx biome ci .
CI 以外再本地挡一次:推到远端前如果有任何 diagnostic,直接拦下——省下一轮 CI 时间。
8.9 自动 PR 注释:Danger/custom bot
如果你希望 PR 评论里看到 lint 摘要,可用 Danger JS + biome 的 JSON reporter:
// dangerfile.ts
import { execSync } from 'node:child_process';
const out = execSync('biome ci --reporter=json . || true').toString();
const { summary, diagnostics } = JSON.parse(out);
if (diagnostics.length > 0) {
markdown(`### Biome 报告 (${summary.errors} errors)\n...`);
}
8.10 常见 CI 陷阱
- ESLint 旧脚本未删 → CI 里跑了两遍 lint,时间翻倍
- 本地 node_modules 被提交进仓库 → Biome 会"顺手"检查它们,CI 炸出上千错误。修:.gitignore 正确且
vcs.useIgnoreFile: true - Docker 镜像里没 git,
--changed会报错 → 改用全量biome ci .或确保镜像包含 git - 行尾差异 LF vs CRLF → 在 biome.json 写死
"lineEnding": "lf",Git 配置core.autocrlf=false
小结
CI 里只要 biome ci . 一行;加 --changed --since=origin/main 应对大仓库;用缓存 action 把重复运行拉到亚秒级;客户端用 husky 提前挡一层。配完这条流水线,团队就告别了"合了才发现 lint 挂"的尴尬。下一章进入 monorepo 专题。