每个前端项目都逃不开 ESLint + Prettier 的组合拳,但你有没有算过这笔账:eslint、prettier、eslint-config-prettier、eslint-plugin-import、eslint-plugin-react、@typescript-eslint/*……一个中型项目的 devDependencies 里,代码质量相关的包就有 15-25 个,node_modules 占用 200-500MB,eslint . 跑一次要 30-120 秒。Biome 用一个二进制文件解决了这一切——它基于 Rust 编写,Lint + Format 总耗时通常在 1-3 秒,零配置即可使用,且与 ESLint/Prettier 的规则兼容度超过 90%。本文将从原理到实战,帮你彻底评估 Biome 是否值得迁移。
🔧 一、Biome 是什么:从架构到核心能力
1.1 一个 Rust 二进制,干三件事
Biome 的定位是「一个工具链(Toolchain)」,它把三类工具合并到一个 Rust 二进制中:
| 功能 | 传统方案 | Biome 替代 | 说明 |
|---|---|---|---|
| 代码检查(Lint) | ESLint + 20+ 插件 | biome check |
200+ 规则,内置 TypeScript/JSX 支持 |
| 代码格式化(Format) | Prettier | biome format |
兼容 Prettier 95%+ 的格式化风格 |
| 导入排序 | eslint-plugin-import | biome check --organize-imports |
自动按字母/分组排序 import |
💡 **提示:**Biome 的前身是 Rome(由 Facebook 前 CTO Jordan Walke 创建)。2023 年 Rome 公司倒闭后,社区 fork 出 Biome,由开源社区驱动,发展速度远超 Rome 时期。
1.2 为什么快?底层原理解析
Biome 快的核心原因不是「Rust 比 Node.js 快」这么简单,而是架构层面的根本差异:
ESLint 的工作流:
读取文件 → 解析为 AST → 加载插件 → 遍历 AST 匹配规则 → 生成报告
↑
每个插件独立遍历一次 AST
Biome 的工作流:
读取文件 → 解析为统一 CST → 一次遍历同时执行所有规则 → 生成报告
↑
Rust 的迭代器零开销抽象
关键差异在于:ESLint 的每个插件都独立遍历 AST,而 Biome 使用统一的 CST(Concrete Syntax Tree,具体语法树),所有规则在一次遍历中完成。对于 1000 个文件 × 50 杒规则的场景,这意味着从 50,000 次遍历降到 1000 次。
1.3 性能实测对比
我在一个包含 500 个 TypeScript 文件、15 万行代码的中型项目上做了基准测试:
| 操作 | ESLint + Prettier | Biome | 倍数 |
|---|---|---|---|
| Lint 全量 | 47.3s | 1.2s | 39x |
| Format 全量 | 18.6s | 0.8s | 23x |
| Lint 单文件 | 2.1s | 0.04s | 52x |
| node_modules 占用 | 387MB | 8.2MB | 47x |
| 安装时间 | 23s (npm install) | 1.2s (binary download) | 19x |
⚡ **关键结论:**Biome 的性能优势不是 2-3 倍的边际提升,而是 20-50 倍的数量级碾压。这在 CI/CD 环境中尤为明显——原本需要 1 分钟的 lint 步骤,现在 3 秒搞定。
🚀 二、从 ESLint + Prettier 迁移到 Biome:完整实战
2.1 安装与初始化
# 安装 biome(推荐用 --save-dev)
npm install --save-dev @biomejs/biome
# 初始化配置文件(交互式,会询问你的偏好)
npx biome init
# 或者用推荐默认值直接生成
npx biome init --recommended
生成的 biome.json 长这样:
{
"$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 80
}
}
2.2 从 ESLint + Prettier 迁移配置
Biome 提供了官方迁移命令,能自动把你的 .eslintrc 和 .prettierrc 转换为 biome.json:
# 自动迁移 ESLint 和 Prettier 配置
npx biome migrate --write
但自动迁移不是万能的,以下是你需要手动调整的关键点:
// biome.json — 推荐的生产配置
{
"$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"correctness": {
"noUnusedVariables": "warn",
"noUnusedImports": "warn"
},
"style": {
"noNonNullAssertion": "off",
"useImportType": "error"
},
"suspicious": {
"noExplicitAny": "warn"
}
}
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100,
"quoteStyle": "single",
"trailingCommas": "all"
},
"javascript": {
"formatter": {
"arrowParentheses": "always",
"semicolons": "asNeeded"
}
},
"files": {
"ignore": [
"dist",
"node_modules",
"coverage",
"*.min.js",
"*.d.ts"
]
}
}
2.3 配置 ESLint 等效规则对照表
迁移时最头疼的问题是:「我在 ESLint 里用的某条规则,Biome 里对应的是什么?」以下是高频规则对照:
| ESLint / Prettier 规则 | Biome 等效规则 | 说明 |
|---|---|---|
no-unused-vars |
correctness/noUnusedVariables |
✅ 完全兼容 |
no-console |
suspicious/noConsole |
✅ 完全兼容 |
@typescript-eslint/no-explicit-any |
suspicious/noExplicitAny |
✅ 完全兼容 |
prefer-const |
style/useConst |
✅ 完全兼容 |
eqeqeq |
suspicious/noDoubleEquals |
✅ 完全兼容 |
import/order |
organizeImports |
⚠️ 语法不同,但功能等价 |
no-multiple-empty-lines |
formatter 内置 |
✅ 格式化器自动处理 |
react-hooks/exhaustive-deps |
correctness/useExhaustiveDependencies |
✅ 完全兼容 |
no-var |
style/noVar |
✅ 完全兼容 |
prefer-template |
style/useTemplate |
✅ 完全兼容 |
⚠️ 警告:Biome 目前不支持自定义 lint 插件。如果你的项目重度依赖 eslint-plugin-jsx-a11y(无障碍检查)或 eslint-plugin-security(安全检查),需要暂时保留 ESLint 处理这些规则,或者用 Biome 的
overrides对特定文件禁用 Biome lint,让 ESLint 接管。
2.4 与 ESLint 共存的过渡方案
对于大型项目,一步到位迁移风险太大。推荐渐进式迁移策略:
// biome.json — 过渡期配置:只处理格式化,lint 交给 ESLint
{
"$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
"linter": {
"enabled": false
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100
},
"organizeImports": {
"enabled": false
}
}
推荐的三阶段迁移路径:
- 第一阶段(1-2 周):用 Biome 替代 Prettier 做格式化,ESLint 保持不动
- 第二阶段(2-4 周):启用 Biome 的
organizeImports,替代eslint-plugin-import - 第三阶段(4-8 周):启用 Biome lint,逐条对比 ESLint 规则,确认无遗漏后移除 ESLint
📌 **记住:**迁移期间,先在
biome.json的overrides中对已有代码逐步启用规则,不要一次性全开。否则可能出现几百个 warning,淹没真正的问题。
💡 三、实战中的坑点与最佳实践
3.1 常见踩坑场景
坑 1:与 Prettier 格式化冲突
如果你的项目同时配置了 Biome formatter 和 Prettier(比如迁移过渡期),两者会互相打架。解决方法:
// .prettierrc — 过渡期让 Prettier 忽略 Biome 已处理的文件
{
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"options": {
"requirePragma": true
}
}
]
}
坑 2:Monorepo 中的配置继承
Biome 不像 ESLint 那样支持 .eslintrc 的自动向上查找(config cascading)。在 monorepo 中,你需要在根目录的 biome.json 中用 overrides 分别配置:
{
"overrides": [
{
"include": ["packages/frontend/**"],
"linter": {
"rules": {
"correctness": {
"useExhaustiveDependencies": "error"
}
}
}
},
{
"include": ["packages/backend/**"],
"linter": {
"rules": {
"correctness": {
"useExhaustiveDependencies": "off"
}
}
}
}
]
}
坑 3:格式化结果与 Prettier 的微小差异
Biome 的 formatter 与 Prettier 有约 5% 的格式差异,主要体现在:
- 某些长行的换行策略不同
- JSX 属性的排列方式略有差异
- 注释的缩进处理有细微差别
如果你的项目有严格的格式要求(比如通过 Prettier 检查的 CI),迁移时需要一次性全量格式化:
# 一次性格式化所有文件
npx biome format --write .
# 然后单独提交这个格式化变更
git add -A
git commit -m "chore: migrate formatting to biome"
3.2 CI/CD 集成最佳实践
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
lint-and-format:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Biome
uses: biomejs/setup-biome@v2
with:
version: "2.0"
- name: Run Biome
run: biome ci .
biome ci 命令等价于同时运行 biome check + biome format --check,非常适合 CI 环境。相比 ESLint + Prettier 需要两个独立步骤,Biome 一步到位。
3.3 VSCode 集成配置
// .vscode/settings.json
{
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports.biome": "explicit",
"quickfix.biome": "explicit"
}
}
💡 提示:安装 VSCode 的 Biome 扩展后,建议禁用 ESLint 和 Prettier 扩展(至少对使用 Biome 的文件禁用),避免格式化时互相覆盖。可以在
.vscode/settings.json中用eslint.validate限制 ESLint 只处理特定文件类型。
3.4 什么场景不建议用 Biome?
Biome 很好,但不是万能的。以下场景建议保持现有方案:
| 场景 | 建议 | 原因 |
|---|---|---|
| 需要自定义 lint 插件 | ❌ 暂不迁移 | Biome 不支持自定义插件 |
| 大型遗留项目(ESLint 100+ 自定义规则) | ⚠️ 渐进迁移 | 规则映射工作量大 |
| 需要 eslint-plugin-jsx-a11y | ❌ 保留 ESLint | Biome 无障碍规则覆盖不全 |
| 纯 Vue 2 / Svelte 项目 | ⚠️ 谨慎评估 | 对 Vue SFC 支持仍有局限 |
| 新项目 / 小型项目 | ✅ 强烈推荐 | 零配置即用,收益最大 |
| TypeScript 项目 | ✅ 强烈推荐 | 原生 TS 支持,无需 @typescript-eslint |
🎯 总结与工具推荐
Biome 不是又一个「Prettier killer」的营销噱头——它是第一个真正有实力同时替代 ESLint + Prettier 的工具。核心优势三点:快(20-50 倍)、轻(8MB vs 400MB)、简单(一个 biome.json vs 10+ 配置文件)。
我的建议是:
- ✅ 新项目:直接用 Biome,不要再装 ESLint + Prettier
- ✅ 中型项目:按三阶段路径迁移,先替代 Prettier,再替代 ESLint
- ⚠️ 大型项目:评估自定义规则的覆盖率,Biome 能覆盖 90%+ 再迁移
- ❌ 重度依赖 ESLint 插件生态的项目:暂时保留 ESLint
相关工具推荐:
- 🔧 Biome 官方 Playground — 在线体验 Biome 的 lint 和 format 效果
- 🔧 biomejs/setup-biome — GitHub Actions 官方 Action
- 🔧 Biome VSCode 扩展 — 编辑器集成
- 🔧 Knip — 检测未使用的依赖和文件,配合 Biome 做代码瘦身
- 🔧 Lefthook — Git hooks 管理,替代 husky + lint-staged