适用于 Oxlint 与 Oxfmt 的 Oxc 优先工作流

程沛权2026/4/14 01:30:00
Star on GitHub

很早之前就对 Oxc 这个项目一直保持关注,看到前段时间开始进入 1.x 版本,一直想弄一套配置,这几天终于有时间搞一下。

不过目前阶段 OXLint 还是无法完整替代 ESLint ,只能是以 OXLint 为主, ESLint 为辅,但是两者可以完美结合,对项目来说,仍然可以以一套 Lint 方案去解决代码问题, OXFmt 倒是可以完美代替 Prettier 原生规则,只是部分插件仍然需要取舍,例如 Markdown 的盘古之白格式化,我只能暂时舍弃。

由于需要两套 Lint 同时工作,所以这个配置包还没有正式定名为 oxc-config ,暂时只称之为 Integration ,一个集成方案或者说是一套工作流。

这是我在 GitHub 上发布的一个开源项目。如果它对你有帮助,欢迎前往 bassist 点一个 Star。

@bassist/oxc-integration 是一个 Oxc 优先的工作流包,适合希望现在就用上带类型提示的 oxlint.config.tsoxfmt.config.ts,同时在 Oxc 能力尚未完全覆盖时保留 ESLint 兜底能力的项目。

使用方法

通常只需要四步:

  1. 安装依赖(参考:安装
  2. 添加 oxlint.config.ts(参考:Oxlint 快速开始
  3. 添加 oxfmt.config.ts(参考:Oxfmt 快速开始
  4. 只有在项目需要 fallback coverage 时,再补 eslint.config.js(参考:ESLint Fallback 快速开始

安装

npm i -D oxlint oxfmt @bassist/oxc-integration

如果你的项目需要 ESLint fallback,请再安装对应框架所需的 ESLint 生态依赖。

编辑器设置

oxlint / eslint 的 CLI 检查结果,与编辑器里的实时诊断并不是同一件事。

如果你希望在编码过程中就获得 Oxc 的实时 lint 提示,还需要额外安装对应的编辑器插件。否则就可能出现“执行 lint 命令时能查出错误,但编辑器里没有任何 提示”的情况。

  • VS Code / Cursor:安装官方 oxc.oxc-vscode 扩展
  • 其他编辑器:参考 Oxc 官方的编辑器接入文档

官方文档: https://oxc.rs/docs/guide/usage/linter/editors.html

Oxc 的编辑器扩展会通过项目本地的 oxlint --lsp 工作,因此也请确保项目的 devDependencies 里已经安装了 oxlint

如果你使用 VS Code 或 Cursor,也可以在项目里补一个 .vscode/settings.json,让保存时修复和类型感知检查更完整:

{
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "always",
    "source.fixAll.oxc": "always"
  },
  "oxc.typeAware": true
}
  • source.fixAll.oxc 用于通过 oxc.oxc-vscode 扩展启用 Oxc 的保存时自动修复
  • oxc.typeAware: true 可以在 TypeScript 项目里提供类型感知诊断
  • 如果你的项目还保留 eslint.config.js 作为 fallback layer,建议继续保留 source.fixAll.eslint
  • 如果项目已经是纯 Oxlint 工作流,可以移除 ESLint 的保存时动作

定位

  • 如果你需要当前稳定、完整的 ESLint 优先方案,请使用 @bassist/eslint-config
  • 如果你想采用 Oxc 优先的工作流,请使用 @bassist/oxc-integration
  • 可以把它理解为未来 @bassist/oxc-config 的过渡形态

工作方式

@bassist/oxc-integration 采用 Oxc-first workflow:

  • oxlint 是主 Linter
  • eslint 是兜底 Linter,用来补齐 Oxc 还没完全覆盖的规则
  • oxfmt 是主 Formatter

这也是为什么某些项目现在仍然会同时保留 oxlint.config.tseslint.config.js。 它们不再是两个并列的主配置文件,而是:

  • oxlint.config.ts:主 Lint 配置
  • eslint.config.js:兜底 Lint 配置

在这些 fallback presets 内部,会自动接入 eslint-plugin-oxlint,用于关闭那些已经由 Oxlint 覆盖的 ESLint 重叠规则。

什么时候需要 ESLint Fallback

如果 Oxc 已经足够覆盖你的项目,可以只使用 oxlint.config.ts。 如果项目仍然依赖框架或生态特定的 ESLint 能力,则再补一个 eslint.config.js

通常可以这样理解:

  • base / node:很多场景只用 Oxlint 就够了
  • react:大多数情况下可以 Oxc 优先,但很多项目仍建议保留 ESLint fallback
  • vue:默认建议保留 ESLint fallback
  • next:默认建议保留 ESLint fallback
  • tailwindcss:如果项目使用 Tailwind CSS 原子类,建议补上 ESLint fallback
  • vitest:如果你需要更完整的测试规则,建议保留 ESLint fallback

内建的 Fallback Coverage

当前 @bassist/oxc-integration 已内建这些 ESLint fallback presets:

  • javascript
  • typescript
  • jsx
  • imports
  • markdown
  • react
  • tailwindcss
  • vue
  • next
  • vitest

当前暂不纳入这个 Oxc-first 工作流范围的内容:

  • lint-md
  • 基于 Prettier 的 Markdown 内容工作流

这些能力后续可以单独作为内容层工作流再设计。

配置总览

项目类型oxlint.config.tseslint.config.jsoxfmt.config.ts
Base TS/JS必需可选必需
Node必需可选必需
React必需推荐必需
Vue必需推荐必需
Next必需推荐必需

Oxlint 快速开始

Base TS/JS

// oxlint.config.ts
import { defineOxlintConfig, oxlintPresets } from '@bassist/oxc-integration'

export default defineOxlintConfig(oxlintPresets.base())

React

// oxlint.config.ts
import { defineOxlintConfig, oxlintPresets } from '@bassist/oxc-integration'

export default defineOxlintConfig(oxlintPresets.react(), oxlintPresets.vitest())

Vue

// oxlint.config.ts
import { defineOxlintConfig, oxlintPresets } from '@bassist/oxc-integration'

export default defineOxlintConfig(oxlintPresets.vue(), oxlintPresets.vitest())

如果你需要官方 oxlint 类型,请直接从 oxlint 包导入,而不是从本包导入。

Oxlint 内建默认值

oxlintPresets.base() 并不是空壳,它已经内置了这个包约定的 Oxc 基线配置。

当前内建默认值包括:

  • plugins:typescriptoxc
  • categories:
    • correctness: error
    • suspicious: error
    • pedantic: warn
    • style: off
  • 基础规则覆盖:
    • typescript/no-explicit-any: off

然后更高层的 presets 会在这份基线上继续扩展:

  • oxlintPresets.node() 会补充 Node 运行时环境
  • oxlintPresets.react() 会补充 reactreact-perfjsx-a11y
  • oxlintPresets.vue() 会补充 vue
  • oxlintPresets.vitest() 会补充 vitest

如何扩展 Oxlint Presets

建议先使用内建默认值,再把项目特有的差异作为额外配置传入。

// oxlint.config.ts
import { defineOxlintConfig, oxlintPresets } from '@bassist/oxc-integration'

export default defineOxlintConfig(oxlintPresets.react(), {
  rules: {
    'no-console': 'warn',
  },
  ignorePatterns: ['fixtures/**'],
})

可以把 presets 理解成默认基线,把额外传入的对象理解成项目级扩展层。

ESLint Fallback 快速开始

Vue / Next / 复杂 React 项目

// eslint.config.js
import { defineEslintConfig, eslintPresets } from '@bassist/oxc-integration'

export default defineEslintConfig(
  eslintPresets.imports(),
  eslintPresets.react(),
  eslintPresets.tailwindcss(),
  eslintPresets.vitest(),
)

如果是 Vue 项目,把 react() 换成 vue() 即可。 如果是 Next 项目,请使用 next()。 只有项目真的在使用 Tailwind CSS 时,才需要再加上 tailwindcss()

Markdown 内容 lint

// eslint.config.js
import { defineEslintConfig, eslintPresets } from '@bassist/oxc-integration'

export default defineEslintConfig(eslintPresets.markdown())

如果你只想为 Markdown 文件开启独立的 lint 行为,而不希望把它并入 lint-md 或基于 Prettier 的内容工作流,可以使用 markdown()

Oxfmt 快速开始

建议优先使用带类型提示的 oxfmt.config.ts,这样配置结构会与官方 formatter API 保持一致。

// oxfmt.config.ts
import { defineConfig } from 'oxfmt'
import { oxfmtConfig } from '@bassist/oxc-integration'

export default defineConfig(oxfmtConfig)

如果你想覆盖默认值:

// oxfmt.config.ts
import { defineConfig } from 'oxfmt'
import { getOxfmtConfig } from '@bassist/oxc-integration'

export default defineConfig(
  getOxfmtConfig({
    semi: true,
  }),
)

oxfmt . 会自动发现 oxfmt.config.ts,所以通常不需要额外显式传入配置路径。

如果你需要官方 formatter 类型,请直接从 oxfmt 包导入,而不是从本包导入。

推荐脚本

{
  "scripts": {
    "lint": "oxlint .",
    "lint:eslint": "eslint .",
    "lint:full": "npm run lint && npm run lint:eslint",
    "format": "oxfmt ."
  }
}

推荐用法:

  • base / node 项目先从 lint 开始
  • vuenext、以及较复杂的 react 项目默认建议使用 lint:full