把前端 lint 闸口交给 Oxlint 前,我会先拆清规则迁移和 CI 预算
导语:前端项目的 lint 速度问题,往往到 monorepo 变大后才集中爆发。一次提交改了几行代码,却要等完整 ESLint 扫描、类型检查和格式化链路跑完,开发者会自然绕开本地检查,把压力推给 CI。Oxlint 的吸引力在于把 JavaScript 和 TypeScript linting 放进 Rust 工具链里,官方文档列出 JS、TS、JSX、TSX,以及 Vue、Svelte、Astro 文件中 script 块的支持范围,还列出 841 条内置规则、自动修复、ignore、多文件分析和 type-aware linting 等能力。我的处理方式是先把它当成 lint 闸口的迁移工程,不急着一次替换所有 ESLint 规则。

原创示意图:把规则盘点、迁移映射、双跑对照、type-aware 检查和 CI 预算放进同一条可收紧链路。 来源:Codex image generation
先盘规则和插件边界
第一步先别改命令,先把现有 ESLint 配置拆成三类:语言基础规则、框架或 import 规则、团队自定义规则。Oxlint 官方迁移页推荐使用 @oxlint/migrate 辅助从 ESLint 迁移,也说明可以在超大或复杂仓库里增量迁移。这里的关键是先生成一张规则映射表,标出哪些规则已由 Oxlint 覆盖,哪些还依赖现有 ESLint 插件,哪些属于团队私有约束。
我会先在分支里跑一次自动迁移,再人工看生成的 oxlintrc 配置。能自动修复的规则先保持 warning,影响行为判断或安全边界的规则先不打开。对 import cycle、未处理 promise、unsafe assignment 这类跨文件或类型相关问题,单独标注数据来源,避免把所有规则都塞进同一条快速路径。
增量共跑比一次切换更稳
大仓库最怕看似轻量的工具替换引发大量历史噪音。Oxlint 文档提供了两条方向:多数项目可以替换 ESLint,复杂仓库可以先跑 Oxlint,再继续保留 ESLint 处理剩余规则。我的默认路径是共跑两周。第一周只让 Oxlint 输出报告,不阻塞合并;第二周用 eslint-plugin-oxlint 关闭重叠 ESLint 规则,让两边职责分开;第三周再把稳定规则升级为 CI 必过项。
这条路径的好处是每一次变更都有对照。若 Oxlint 和 ESLint 对同一文件给出不同结果,先归入迁移清单,暂缓让业务同学批量改代码。迁移清单记录规则名、文件类型、触发样例、是否可自动修复、是否需要插件兜底。等样例足够稳定,再把对应规则移进主干配置。
type-aware 检查要独立预算
很多团队会把 lint 和 TypeScript 类型检查混在一起看。Oxlint 的 type-aware linting 由 tsgolint 提供,并接入 Oxlint CLI 和配置系统。它适合处理依赖类型信息的规则,比如未处理 promise 或 unsafe assignment,但它也意味着更多项目上下文和更高资源消耗。我的做法是把 type-aware 检查拆成第二层闸口:普通 Oxlint 负责快速反馈,type-aware 负责主分支和合并请求上的高风险判断。
配置上可以先为 type-aware 单独设 max warnings,不和基础 lint 共用预算。普通 lint 超预算直接失败,type-aware 初期只记录趋势。等历史问题消化到可控数量,再把预算逐步收紧。这样速度收益留给日常开发,深度检查留给真正需要质量门槛的位置。
CI 闸口要能解释失败
Oxlint 的 CI 文档提到可以在 GitHub Actions 环境里输出更好的 warning 和 error annotations,也提供 CI 与 hook 场景的设置参考。我会在 CI 里保留三份产物:终端摘要、机器可读报告、迁移清单链接。失败信息只说规则名还不够,还要能告诉开发者这是新增问题、历史债务、迁移差异还是 type-aware 预算超限。
最后的上线标准很简单:本地命令足够快,CI 失败可解释,旧规则没有静默消失,新规则能逐步收紧。Oxlint 适合先承接高频、清晰、可自动修复的那部分 lint 工作,再慢慢接管更复杂的插件和类型规则。这样迁移带来的收益会落到一条能持续收紧的代码质量闸口上。