配了八年 ESLint,今天才发现 flat config 根本不是答案——这件事今天被 Oxlint 从根上彻底原生化了
每次 git push 之后,站在 CI 日志前等三分钟看 lint 结果——这件事做了八年,没人觉得有问题。
不是你的网速慢,不是你的 CI 机器差。是 ESLint 本身就是单线程的 JavaScript 程序,检查 500 个文件就要跑 500 次串行循环,和你本地 vscode 保存时的卡顿是同一个病根。
今年升级 ESLint 9 的时候,团队花了三周迁移 flat config,配置文件从 .eslintrc.js 的一坨对象变成了 eslint.config.js 里的数组——语法变好看了,但 lint 还是那么慢。三周换了个写法,性能一分没提。
这件事的答案,今天被 Oxlint 从根上换了。
Oxlint 是什么
Oxlint 是 VoidZero 团队出品的 Rust 原生 linter,和 Rolldown/Vite 8 是同一套底层基础设施。它不是 ESLint 的配置优化,而是从架构上换了跑道:多线程并行扫描 AST,而不是 ESLint 的单线程循环。
关键数据说话:
| 工具 | 500 文件耗时 | 说明 |
|---|---|---|
| ESLint 9 flat config | ~14s | 单线程,TypeScript aware |
| Oxlint | ~0.15s | 多线程并行,600+ 规则 |
MakerKit 实测:原来 lint + format 要 20s+,切到 Oxlint + Oxfmt 后总共 ~500ms。Shopify 内部数据:ESLint 跑 75 分钟的检查,Oxlint 10 秒跑完。
这不是跑分成绩,是 CI 账单和 pre-commit hook 等待时间的真实差距。
迁移路径一:自动迁移工具
如果你已经跑在 ESLint 9 flat config 上,有一行命令可以直接生成 Oxlint 配置:
npx @oxlint/migrate
这个工具会:读取你的 eslint.config.js、把支持的规则转换成 .oxlintrc.json、保留规则严重性和路径覆盖、转换 globals 为 Oxlint 等价写法、保留 ignore 模式。生成完直接跑 npx oxlint 验证,有问题的规则再手动修。
迁移路径二:hybrid 方案(ESLint + Oxlint 共存)
Oxlint 目前缺少 type-aware 规则(no-floating-promises/no-misused-promises 这类需要 TypeScript 类型信息的规则),如果你的项目重度依赖这些规则,可以先用 eslint-plugin-oxlint 做渐进迁移:
pnpm add -D eslint-plugin-oxlint
// eslint.config.js
import oxlint from 'eslint-plugin-oxlint';
export default [
// ... 其他插件配置 ...
oxlint.configs['flat/recommended'], // 放最后,让 Oxlint 规则优先
];
这样 Oxlint 先跑,ESLint 只处理 Oxlint 不支持的 type-aware 规则。两边并行,总时间从纯 ESLint 的 14s 降到 hybrid 的 ~3s(1s oxlint + 2s eslint)。
迁移路径三:NX monorepo 实测数据
Udanyayak.com 记录了一个 NX monorepo 完整迁移过程,5000+ 文件:
- ESLint 单跑:2 分 27 秒
- Oxlint 单跑:1.3 秒(5360 文件,134 规则,11 线程)
- Oxfmt 单跑:2.1 秒(6111 文件)
配置文件从 16 个减到 2 个,npm 依赖从 18 个减到 2 个,lint-staged 配置从 45 行减到 7 行。
三个要注意的坑
第一,type-aware 规则缺口。Oxlint 目前不支持 no-floating-promises、no-misled-promises、strict-boolean-expressions 这类需要 TypeScript 编译器参与的规则。如果你的代码库重度依赖这些,hybrid 方案先跑起来。
第二,部分老旧插件不支持。eslint-plugin-import 的某些规则还没有 Oxlint 原生实现,用 hybrid 方案让 ESLint 处理这部分。
第三,oxlint 报错时 exit code 非零。CI 脚本里要 catch 异常再 parse stdout,直接 [eslint, oxlint] 串行跑的话顺序别写反——Oxlint 放前面,省时间是真实的。
下一步
如果你现在跑在 ESLint 8(legacy config),直接装 Oxlint 跳级,不用先折腾 flat config 迁移。如果你已经在 ESLint 9 flat config,npx @oxlint/migrate 生成配置再手动修。如果你团队用 NX monorepo,eslint-plugin-oxlint 的 hybrid 路径投入产出比最高。把这三分钟从 CI 日志里省下来,下次 git push 可以早点喝咖啡。
评论区
登录后可评论。