🧩 背景:三套工具的「规约地狱」
在做前端工程化时,我们几乎都经历过这样的「工具链堆叠」:
- ESLint:语法、规则、最佳实践;
 
- Prettier:格式化;
 
- Stylelint:样式代码规范;
 
- 再加上 
husky+lint-staged提交钩子; 
起初一切都还好,但随着项目变大、依赖升级、规则冲突、插件失效、配置重复……
更糟糕的是,这些工具带来的性能负担:
- 实时代码检查:每次编辑代码后,ESLint 等工具就会在后台运行,给我的 MacBook Air 带来明显的发热和卡顿;
 
- 提交等待时间:每次 
git commit都要等待 lint-staged 运行完所有检查,少则几秒,多则十几秒,打断开发节奏; 
ESLint 为什么这么慢?
深入研究后,我发现 ESLint 的性能问题并非偶然,而是架构层面的限制:[1]
1. 单线程架构的历史包袱
- ESLint 从诞生到 2025 年 8 月(v9.34.0)才引入多线程支持,十多年来一直是单线程逐个处理文件
 
- 无法充分利用现代多核 CPU,大型项目中浪费了大量计算资源
 
2. JavaScript/Node.js 的性能天花板
- 作为解释型语言,JavaScript 的运行速度本身就比 Rust、Go 等编译型语言慢数十倍
 
- Node.js 的 V8 引擎虽然已经很快,但在 CPU 密集型任务(如 AST 解析)上仍有明显劣势
 
3. TypeScript 类型检查的「黑洞」
typescript-eslint的类型感知规则需要调用 TypeScript 编译器 API[2]
- 第一次运行时缓存未生效,可能导致 7 分钟以上的等待时间
 
- 即使有缓存,复杂项目依然会出现 100% CPU 占用、8GB+ 内存消耗的情况[3]
 
4. AST 转换和选择器引擎的低效
- ESLint 需要将代码解析为抽象语法树(AST),然后用选择器引擎匹配规则[4]
 
- 这个过程在 JavaScript 实现中存在大量性能瓶颈,尤其是处理大文件时
 
5. 默认不启用缓存
- ESLint 虽然支持 
--cache参数,但默认关闭[5] 
- CI 环境中每次都要完整运行,浪费大量时间
 
🧠 我开始思考:有没有一个统一的、快速的、零配置的替代方案?
于是我看向了 Biome。
🚀 Biome:速度惊人的统一工具链
Biome 是由 Rome 团队重构的新一代前端工具链,它最大的特点就是:快,非常快。[1]
为什么选择 Biome?
性能优势:
- 比 ESLint 快数百倍:在大型项目中,ESLint 冷运行可能需要 7 分钟,而 Biome 只需 1.5 秒以内[1]
 
- 比 Prettier 快 35 倍:得益于 Rust 实现,格式化速度是传统工具的数十倍[2]
 
- 与 Prettier 97% 兼容:迁移成本极低,几乎无缝切换[2]
 
- 实时检查零卡顿:ESLint 在大型项目中经常导致编辑器卡顿,Biome 完全不会[3]
 
统一体验:
- Linter(替代 ESLint)
 
- Formatter(替代 Prettier)
 
- Import Sorter(替代 
eslint-plugin-import) 
- 一个工具、一个配置、一条命令
 
开发体验改善:
- 实时检查不再卡顿,MacBook 机身温度也降下来了
 
- Git 提交钩子从十几秒缩短到 1-2 秒
 
- 配置文件从 3 个精简为 1 个(
biome.json) 
💡 对于追求开发效率的团队来说,Biome 不仅仅是"够用",而是真正意义上的性能飞跃。[2]
🪤 踩坑记录
⚠️ 1. “Suppression comment has no effect”
Biome 会检测无效的 
// biome-ignore 注释。最初我拼错了规则路径(少了 
lint/correctness/ 前缀),导致提示:1Suppression comment has no effect. Remove the suppression or make sure you are suppressing the correct rule.
2✅ 解决:使用完整路径,例如:
1// biome-ignore lint/correctness/useUniqueElementIds: static id is safe here
2<div id="fixed" />
3⚠️ 2. “Some errors were emitted while applying fixes.”
表示 Biome 在自动修复时遇到无法安全修改的内容。
原因通常是复杂语法或冲突的格式化规则。
✅ 解决:
查看命令行详细输出,手动修复有问题的文件,再运行 
biome check --write。⚠️ 3. “静态 id 不允许”
Biome 禁止在 JSX 中写死 
id="xxx"(规则:useUniqueElementIds)。目的是防止 React SSR/水合时重复 ID。
✅ 解决:
1import { useId } from "react";
2
3const id = useId();
4return <input id={id} />;
5或局部禁用规则:
1// biome-ignore lint/correctness/useUniqueElementIds: safe for static DOM
2⚠️ 4. “eslint [ENOENT]”
项目已经不用 ESLint,但 lint-staged 还在调用它。
日志长这样:
1[FAILED] eslint [ENOENT]
2husky - pre-commit script failed (code 1)
3✅ 解决:
删除 
.lintstagedrc.mjs,改为在 package.json 中直接配置 Biome。⚙️ 最终产物:干净的工程配置
1{
2  "lint-staged": {
3    "**/*.{js,jsx,ts,tsx,css,scss,md,json}": "pnpm exec biome check --write --no-errors-on-unmatched"
4  },
5  "scripts": {
6    "check": "biome check .",
7    "fix": "biome check --write .",
8    "format": "biome format --write ."
9  }
10}
11- 没有 
.eslintrc.* 
- 没有 
.prettierrc 
- 没有 
.stylelintrc 
- 配置文件总量从 3 个缩减为 1 个
 
提交速度更快,CI 日志更干净。
💡 经验总结
主题  | 经验总结  | 
性能  | Biome 格式化和 lint 速度比 ESLint + Prettier 快约 5-10 倍  | 
兼容性  | 对 TS / JSX 支持稳定;SCSS/嵌套语法需谨慎  | 
学习成本  | 低,规则命名清晰、配置统一  | 
工程复杂度  | 极大简化:一个配置、一个命令、一个依赖  | 
团队落地  | 推荐从新项目或轻量项目先行试点,再推广  | 
🧭 总结
迁移到 Biome 后,我最大的感受是:
🧹 工程“清爽”了,🚀 提交钩子更快了,🧠 心智负担更小了。
虽然它暂时还没完全覆盖 Stylelint 的所有规则,但对于大多数前端项目来说,Biome 已经足够稳定、足够快、足够省心。
下一步计划:
- 跟踪 Biome 对 SCSS / CSS-in-JS 的支持;
 
- 等官方 Stylelint 替代层稳定后,彻底移除 stylelint;
 
- 用 
biome.json维护团队统一代码规范。 
如果你正在犹豫是否要迁移到 Biome ——✨ 我建议:大胆试试看,从你最小的项目开始。你会感受到一个「现代」前端工具该有的样子。
Follow Me | 关注我
- Blog:https://harryis.fish
 
- X(CN): @harry_is_fish
 
- X(EN): @harry_isfish
 
- 公众号
 

- 📺 Bilibili:海鱼Harry
 
- 🍠 小红书:海鱼Harry
 
- 🎵 抖音:海鱼Harry