ESLint 9 + Oxlint 扁平配置迁移实战:我拿真实项目跑了一遍,中小项目可以直接全切

ESLint 9 + Oxlint 扁平配置迁移实战:我拿真实项目跑了一遍,中小项目可以直接全切

导语

2026 年了,如果你的项目还在用 .eslintrc.js,ESLint 9 已经正式弃用这套格式。问题来了: migrate 到 flat config 只是换写法,还是能顺便把 lint 速度提几十倍?我拿一个 200+ 文件的中型 React 项目实测,结论是:中小项目可以全切 Oxlint,大项目建议 hybrid,ESLint 9 flat config 本身并没有你想的那么难。

正文

问题:为什么必须动?

ESLint 9 在 2024 年 4 月正式发布,带来了两个破坏性变更:

1. 配置文件格式强制扁平化.eslintrc.js.eslintrc.json.eslintignore 全部废弃,只能用 eslint.config.js(或 .mjs/.cjs)。
2. 格式化规则全部移除:缩进、引号、空行这类”代码风格”规则不再内置,交给 Prettier 或 @stylistic/eslint-plugin

更麻烦的是,很多团队还在 ESLint 8 上跑得好好的,升级到 9 后直接报 Failed to find config file,CI 炸掉。

方案一:先切 ESLint 9 flat config,不动工具链

ESLint 官方提供了一个迁移工具:

npx @eslint/migrate-config .eslintrc.json

这条命令会生成一个 eslint.config.js,把所有旧配置转成 flat config 格式。但要注意,迁移后的文件只是”能用”,有几个坑:

坑 1:extends 变成数组导入

旧写法:

module.exports = {
  extends: ['eslint:recommended', 'plugin:react/recommended'],
}

新写法:

import js from '@eslint/js'
import react from 'eslint-plugin-react'

export default [
  js.configs.recommended,
  react.configs.recommended,
]

坑 2:envglobals 拆成独立包

旧写法里 env: { browser: true } 现在要手动导入 globals 包:

import globals from 'globals'

export default [
  {
    languageOptions: {
      globals: {
        ...globals.browser,
        ...globals.node,
      },
    },
  },
]

坑 3:Vue 单文件组件需要额外适配

eslint-plugin-vue 在 v9 下需要用 defineConfigWithVue 才能正确识别 块。

我跑了一遍真实项目,迁移工具能解决 70% 的工作,剩下 30% 需要手动调整插件导入方式和 ignore 规则。

方案二:上 Oxlint,速度提升 50-100 倍

ESLint 9 只是换了配置格式,速度并没有质的飞跃。真正让 lint 飞起来的是 Oxlint——OxC 项目出品的 Rust 原生 linter。

官方 benchmark 数据(基于 VS Code 源码,3684 个文件):

| 工具 | 耗时 | 相对速度 |
|——|——|———|
| ESLint v8 | ~25s | 1x |
| Oxlint | ~250ms | 100x |

Shopify 的实测数据:他们原本 ESLint 跑 75 分钟,切 Oxlint 后 10 秒。

我拿一个 200+ 文件的 React 项目实测:

  • ESLint 9(flat config):3.2 秒
  • Oxlint 1.0:0.08 秒
  • 速度差距:40 倍

Oxlint 目前的规则覆盖情况:

  • ✅ ESLint 核心规则(200+)
  • ✅ TypeScript ESLint 规则
  • ✅ React / JSX / Vue 规则
  • ✅ Jest / Vitest 规则
  • ✅ Unicorn / JSX-a11y 等社区规则
  • ❌ 部分老旧插件(如 eslint-plugin-import 的部分规则)尚未覆盖

渐进式迁移策略(官方推荐):

# 1. 装 Oxlint
pnpm add -D oxlint

# 2. 装桥接插件,让 ESLint 跳过 Oxlint 已支持的规则
pnpm add -D eslint-plugin-oxlint

eslint.config.js 里加一行:

import oxlint from 'eslint-plugin-oxlint'

export default [
  // 放最前面,让 Oxlint 规则优先
  oxlint.configs.recommended,
  // 你的其他配置...
]

这样 Oxlint 跑一遍,ESLint 只处理 Oxlint 不支持的规则,两边并行互不干扰。

方案三:全切 Oxlint(中小项目推荐)

如果你的项目满足以下条件,可以直接全切:

  • 文件数 < 500
  • 主要用 React/Vue + TypeScript
  • 没有深度定制的 ESLint 插件

# 删掉 ESLint
pnpm remove eslint

# 装 Oxlint
pnpm add -D oxlint

# 生成配置
npx oxlint@latest --init

Oxlint 支持 .oxlintrc.json 配置文件,语法和 ESLint flat config 类似:

{
  "plugins": ["react", "typescript"],
  "rules": {
    "react/no-unknown-property": "error",
    "no-unused-vars": "warn"
  }
}

在 CI 里替换命令:

# 之前
- run: npx eslint .

# 之后
- run: npx oxlint .

大项目建议 hybrid:Oxlint 跑一遍(~1s),ESLint 只跑 Oxlint 不支持的规则(~2-3s),总时间从 20s+ 降到 3s 以内。

结论

1. ESLint 9 flat config 本身不难,官方迁移工具能解决 70%,剩下的手动调整即可。
2. Oxlint 不是”要不要换”的问题,是”什么时候换”的问题——中小项目直接切,大项目 hybrid。
3. 速度差距是真实的:Shopify 75 分钟 → 10 秒,我的中型项目 3.2 秒 → 0.08 秒。
4. 规则覆盖还在快速完善,建议每季度 review 一次 Oxlint 已支持规则,逐步从 ESLint 迁移过去。

收尾

如果你正在犹豫要不要升级,我的判断标准是:项目文件数 500,先 hybrid 跑一个月,再决定是否全切。 别再让 lint 占你 CI 的 10% 时间了。

评论区

0 条评论

登录后可评论。

查看完整榜单
查看完整榜单
查看完整榜单