被ESLint折磨了大半年,上周终于下定决心换成了Biome。速度是真的飞起,但中间踩的坑也够我喝一壶的。特别是那个Vue项目,差点让我直接回滚。 我们的Vue 3中后台项目,200多个文件,ESLint配了60多条规则,再加Prettier做格式化,CI跑一遍lint+format要两分多钟。组里有人吐槽"提交一次代码等lint等到忘记刚才在改啥"。我当时也没当回事,直到有天晚上debug到凌晨三点,等lint的时间比写代码还长,心态彻底崩了。 那两天正好刷到Biome v2.5.5的发布,511条规则,97%兼容Prettier,Vercel、Cloudflare都在用。我想着反正周末也没事,干脆试试。 手里三个项目:Vue 3中后台(220文件)、React 18 + Next.js 15官网(150文件)、纯Node.js后端(80文件)。打算挨个来。
装是真好装
css
npm i -D --save-exact @biomejs/biome
npx @biomejs/biome init
两行命令,生成一个biome.json,改改配置就能跑。第一次biome check ./src,Vue项目甩给我2000多个报错------当时确实慌了一下。但仔细翻了翻,大头是格式问题,真正的lint错误300多条。 先跑format把格式批量修掉:
perl
npx @biomejs/biome format --write ./src
几秒钟完事。我用time测了一下,Biome格式化220个文件用了不到1秒,Prettier之前要12秒。看到这个数字我愣了有好几秒,反复跑了三遍确认没看错。
Vue项目:差点劝退
先说最痛的那个坑,因为就是它让我差点放弃。 我们的Vue组件用的是<script setup lang="ts">,之前ESLint通过vue-tsc做类型检查------模板里传错prop类型,vue-tsc能在CI阶段直接拦住。 迁完Biome跑了一遍CI,全绿。我还挺得意,跟同事说"换工具就是爽"。
结果过了两天QA报了一个bug:某个表单组件传了错误的prop类型,页面渲染异常。我一查,这个错误以前vue-tsc会直接报错的,现在Biome根本没拦到。 原因是Biome的lint只在语法层面做检查,它不懂类型推导。那种需要类型信息才能判断的问题------比如你传了string给期望number的prop------它完全看不出来。 当时真的想骂人。全绿了两天,以为万事大吉了,结果漏了个生产bug。 后来的解决方案是保留vue-tsc单独跑类型检查,Biome只管lint和format:
json
{
"lint": "biome check ./src",
"format": "biome format --write ./src",
"type-check": "vue-tsc --noEmit",
"ci": "npm run type-check && npm run lint"
}
不是那么"all-in-one",但至少不出事。Next.js那边倒没这个问题,tsc在build阶段已经做了类型检查。
ESLint自定义规则:这个是真没辙
Vue项目有一套自定义ESLint规则------禁止组件里直接操作DOM、限制ref的使用方式、强制某些import顺序。有的是eslint-plugin-vue扩展的,有的是自己写的。 Biome不支持自定义规则。官方文档白纸黑字写着,我当时心存侥幸想去搜搜有没有plugin方案,翻了一圈GitHub issues,确认没有。 最后搞了个很土的折中方案:通用规则迁到Biome(需要做规则名映射,比如ESLint的no-unused-vars对应Biome的noExplicitAny),自定义规则写了个简陋的脚本在CI里单独跑------就是正则加grep,不优雅但能用。
json
{
"linter": {
"rules": {
"recommended": true,
"correctness": {
"noUnusedVariables": "error",
"noUnusedImports": "error"
},
"suspicious": {
"noExplicitAny": "error"
},
"style": {
"useConst": "error",
"noNonNullAssertion": "warn"
}
}
}
}
Node.js后端那个项目就好多了,没多少自定义规则,no-unused-vars、no-console、eqeqeq这些Biome全都原生支持,半小时搞定。
Prettier那3%的不兼容
说实话,3%听起来不多,但对格式有洁癖的人来说体感远不止3%。 Vue项目里有段CSS,注释在属性之间,Biome格式化之后把注释位置挪了。Prettier会保持注释在gap和padding之间,Biome挪到了padding后面。同事review的时候直接问"谁把我注释挪了"。 React项目里更烦------JSX里有一段多行注释解释为什么组件顺序不能改,Prettier会把注释块对齐到特定位置,Biome保持原样。视觉上差几个空格,但代码review的时候看着就是"不舒服"。 我一开始还想着写个脚本强制对齐注释,搞了半小时发现越搞越乱,最后放弃了。在biome.json里把格式冲突的几个文件加到files.ignore,眼不见为净。
IDE那边也有个小插曲
换完Biome忘了改VS Code的defaultFormatter,结果保存文件的时候Biome和Prettier来回打架------Biome改一遍,Prettier又改回来,git status一堆无意义的diff。排查了半小时才反应过来。
json
{
"editor.defaultFormatter": "biomejs.biome",
"editor.codeActionsOnSave": {
"source.organizeImports.biome": "explicit"
}
}
改了配置就没事了。另外Biome的LSP在v2.5.3之前偶尔会卡死,v2.5.5修了这个bug(changelog里提到了issue #10845),升级到最新就稳了。
速度到底有多离谱
跑了三天测下来的数据,环境是MacBook Pro M4、32GB内存: Vue中后台(220文件):全量lint从40多秒降到1秒出头,format从12秒降到不到1秒。单文件检查从将近2秒变成0.03秒,体感就是------点保存的瞬间就已经check完了。 React官网(150文件):全量lint从28秒降到不到1秒。 Node.js后端(80文件):全量lint从11秒降到半秒以内。 CI pipeline变化最大。Vue项目从3分多钟降到1分出头,lint+format环节从2分多钟缩到10秒以内。省出来的时间主要在TypeScript类型检查和其他步骤上------那些Biome管不了的部分。 node_modules体积也轻了,三个项目平均减少了30-40MB。eslint、prettier和一堆插件全部卸掉了,清清爽爽。
最终配置
Vue项目的biome.json完整版(其他两个更简单):
bash
{
"$schema": "https://biomejs.dev/schema.json",
"files": {
"ignore": ["dist/**", "node_modules/**", "src/legacy/**"]
},
"organizeImports": { "enabled": true },
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"correctness": {
"noUnusedVariables": "error",
"noUnusedImports": "error"
},
"suspicious": { "noExplicitAny": "error" },
"style": {
"useConst": "error",
"noNonNullAssertion": "warn",
"useImportType": "error"
},
"nursery": {
"useSortedClasses": {
"level": "warn",
"options": { "functions": ["cn", "clsx"] }
}
}
}
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100
},
"javascript": {
"formatter": {
"quoteStyle": "single",
"semicolons": "always",
"trailingCommas": "all"
}
},
"css": { "formatter": { "enabled": true } }
}
src/legacy/**被ignore了------两年前的老代码,格式惨不忍睹,暂时不想动。
哪些情况别急着换
重度依赖ESLint自定义插件的,别换。你公司自己写的eslint-plugin,Biome替代不了。 对格式有极其严格独特要求的,慎重。如果你有一份100行的.prettierrc,那3%的不兼容会让你很难受。 项目里混合了Biome不支持的语言的,也得考虑。虽然JS/TS/JSON/HTML/CSS/GraphQL都支持了,但.vue模板里的深度检查它还做不了。 但如果只是新项目或者对CI速度有刚需的老项目,我觉得值得试。对我来说,自定义规则的麻烦和不兼容的那些小细节,在30多倍的速度提升面前,都不是事。我选Biome。