跳到主要内容

ESLint

ESLint 的价值,不只在“报几条 warning”。它更像前端项目里的第一道静态质量闸门:

  • 提前发现明显问题
  • 把风险写法拦在提交前
  • 把框架约束接进日常开发
  • 用配置把团队约定写成可执行规则

如果项目已经进入多人协作阶段,ESLint 基本不会缺席。

ESLint 更适合管什么

它最适合处理这些事:

  • 未使用变量
  • 条件分支里的可疑写法
  • 未处理的 Promise
  • anyts-ignore 这类需要控制的边界
  • React Hooks 依赖
  • 导入顺序
  • 禁止某些 API、路径或写法

它不太适合硬扛的,是纯格式问题。缩进、分号、引号这类事情,通常还是交给 Prettier 或 Biome 更顺。

先看现代配置主线

官方现在的主线是 flat config,也就是 eslint.config.js 这套配置方式。ESLint 官方文档明确说明,配置文件可以是 eslint.config.jseslint.config.mjseslint.config.cjs 等形式,并且导出的是配置对象数组。

一个最小例子:

import { defineConfig } from 'eslint/config'
import js from '@eslint/js'

export default defineConfig([
js.configs.recommended,
])

如果项目是 TypeScript、React、Vue,通常还会继续往上叠插件和分目录规则。

一个更常见的前端项目配置

import js from '@eslint/js'
import tseslint from 'typescript-eslint'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import importPlugin from 'eslint-plugin-import'
import globals from 'globals'
import { defineConfig } from 'eslint/config'

export default defineConfig([
{
ignores: ['dist', 'build', 'coverage', 'node_modules'],
},
js.configs.recommended,
...tseslint.configs.recommended,
{
files: ['**/*.{ts,tsx,js,jsx}'],
languageOptions: {
globals: {
...globals.browser,
...globals.node,
},
},
plugins: {
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
import: importPlugin,
},
rules: {
'no-console': ['warn', { allow: ['warn', 'error'] }],
'no-debugger': 'error',
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
'@typescript-eslint/no-explicit-any': 'warn',
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn',
'react-refresh/only-export-components': 'warn',
'import/order': [
'warn',
{
groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
'newlines-between': 'always',
alphabetize: { order: 'asc', caseInsensitive: true },
},
],
},
},
])

这份配置已经能覆盖多数 React + TypeScript 项目的主线需求。

TypeScript 项目里,ESLint 和 tsc 怎么分工

这是最容易混的一层。

tsc 更适合做什么

  • 类型检查
  • 类型推断相关错误
  • TS 编译边界

ESLint 更适合做什么

  • 未使用变量
  • 风格化的 TS 约束
  • any、断言、忽略注释的使用边界
  • 框架和团队层面的静态约束

比较稳的结构通常是:

  • tsc --noEmit 负责类型
  • eslint 负责规则

不要指望 ESLint 替代完整类型系统,也不要把所有 TS 问题都往 ESLint 里塞。

React 项目里最常见的几组规则

Hooks

React 项目里最重要的一组,通常就是:

  • react-hooks/rules-of-hooks
  • react-hooks/exhaustive-deps

这两条看起来普通,实际能挡掉很多后面很难查的问题。

刷新和导出边界

如果项目用了现代开发服务器,react-refresh/only-export-components 这类规则也值得接上。

导入顺序

导入顺序不是“好看而已”。项目一大,模块边界、分层和别名结构会越来越依赖它。

Vue / Next / Node 项目里怎么理解 ESLint

虽然这篇主要从前端项目写,但 ESLint 的思路在这些项目里一样适用:

  • Vue:重点会落在 SFC、组合式 API、模板约束
  • Next:重点会落在 React 规则、框架约束、路由边界
  • Node:重点会落在运行时 API、异步约束、模块边界

同一套 ESLint,不代表所有项目都该用同一份 rules。更稳的方式是:

  • 共享一层基础配置
  • 再按技术栈叠加专属规则

哪些规则更值得早点开

如果项目还在起步期,建议先把“高价值低争议”的规则接上。

例如:

  • no-debugger
  • no-undef
  • @typescript-eslint/no-unused-vars
  • react-hooks/rules-of-hooks
  • import/order

这些通常都比较容易接受,而且收益很直接。

哪些规则别急着一开始拉满

这些规则不是没用,而是更容易在老项目里制造阻力:

  • max-lines
  • complexity
  • max-depth
  • @typescript-eslint/no-explicit-any 直接上 error
  • 过多的命名规则

更稳的方式通常是:

  • 先 warning
  • 先只管新增代码
  • 等团队适应后再逐步抬高强度

Ignore 怎么配

Ignore 这一层非常关键,不然 lint 很容易被构建产物和生成文件拖慢。

常见忽略项:

  • dist
  • build
  • coverage
  • node_modules
  • 自动生成代码目录
  • 某些第三方拷贝文件

flat config 里一般直接写在:

{
ignores: ['dist', 'build', 'coverage']
}

和 Prettier 怎么配

ESLint 和 Prettier 最稳的关系通常是:

  • ESLint 查问题
  • Prettier 管格式
  • eslint-config-prettier 把冲突规则关掉

很多项目不顺,往往就是因为这两层没分清,最后同一份代码被两个工具来回拉扯。

编辑器里怎么接

团队体验好不好,很大一部分取决于编辑器集成。

常见做法:

  • 保存时自动执行 ESLint fix
  • 或至少在编辑器里直接显示诊断

例如 VS Code 常见会配:

{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
}
}

如果项目里还同时开了 Prettier、Biome 或 import organize,保存动作的优先级就要提前想清楚。

Git hooks 和 CI 怎么接

一套更常见的链路是:

  • 本地保存:尽量自动修
  • 提交前:lint staged files
  • CI:lint full project

这样做的好处是:

  • 本地反馈快
  • 提交前能兜底
  • CI 负责最终一致性

老项目迁移到 flat config,通常怎么走

官方有专门的 migration guide。实际项目里更稳的迁移方式一般是:

  1. 先保留原规则意图
  2. 换成 eslint.config.js
  3. 分块迁移 overrides、ignore、plugin config
  4. 迁完后再顺手删历史兼容写法

不要一边迁配置格式,一边大改所有规则,不然排错会很痛苦。

一个更接近真实项目的落地建议

如果要从零接一套 ESLint,比较稳的顺序通常是:

  1. 接基础 recommended
  2. 接 TypeScript 规则
  3. 接框架规则
  4. 接 import 规则
  5. 再看团队定制规则

这样排,排错和协作成本都低很多。

更适合先记住的主线

ESLint 更有价值的地方,不是“规则多”,而是:

  • 把高频问题前移
  • 把团队约定写成机器能跑的东西
  • 把 review 里低价值的争论压下去

规则本身只是手段,团队能长期跑得顺才是目标。

参考来源