ESLint 是什么?为什么你的项目需要它?

从"代码能跑就行"到"代码能跑且优雅",中间隔着一个 ESLint。

一句话回答

ESLint 是一个 JavaScript/TypeScript 代码静态分析工具------它不运行你的代码,而是读你的代码,找出里面的语法错误、坏味道和不一致的风格,然后告诉你哪里该改、怎么改。


为什么需要 ESLint?

1. 拦截低级错误,趁早不赶晚

js 复制代码
// 你觉得这段代码有什么问题?
if (isAdmin = true) {
  deleteUserAccount();
}

= 写成了 ==?不,是赋值写进了 if 条件里。这段代码能跑,不会报语法错误,但它会在你不注意的时候把用户账号删了。ESLint 的 no-cond-assign 规则会在你写下的那一刻就标红警告。

类似的还有:

  • 变量声明了但没使用(no-unused-vars
  • console.log 忘了删(no-console
  • return 后面写了不可达代码(no-unreachable
  • ===== 混用(eqeqeq

这些 bug 在运行时往往很难排查,但在静态分析阶段花 0.1 秒就能发现。

2. 统一团队风格,消灭无意义的 Code Review 争论

"花括号应该写同一行还是换行?" "缩进用 tab 还是空格?" "分号加不加?"

这些问题不该出现在 Code Review 里。它们没有对错,但一旦团队不统一,阅读代码时就会产生认知负担。ESLint 把这些风格决策固化成规则,代码提交前自动检查,不符合就报错。

js 复制代码
// ESLint 让团队的代码长成同一个样子
const foo = () => {
  if (condition) {
    doSomething();
  }
};

3. 强制执行最佳实践

JavaScript 有很多"能跑但不好"的写法。ESLint 内置了大量最佳实践规则:

规则 防止什么
no-var 鼓励用 let/const 替代 var,避免变量提升陷阱
prefer-const 声明后不修改的变量必须用 const
no-eval 禁止 eval(),防止注入攻击
no-implicit-globals 禁止意外创建全局变量
prefer-arrow-callback 鼓励箭头函数,减少 this 绑定问题
no-duplicate-case 防止 switch 里写重复的 case

4. 与编辑器深度集成,实时反馈

VS Code、WebStorm 等编辑器都支持 ESLint 插件。你写代码的同时,编辑器就能:

  • 在有问题的代码下画红色波浪线
  • 显示具体问题和修复建议
  • 一键自动修复--fix

这种"写错即纠"的体验,比等 CI 跑完才发现问题高效得多。


ESLint 的工作原理

ESLint 的核心流程可以概括为三步:

解析 → 遍历 → 报告

  1. 解析 :ESLint 把你的源代码解析成 AST(抽象语法树)。JavaScript 用 Espree 解析器,TypeScript 需要配合 @typescript-eslint/parser
  2. 遍历:ESLint 遍历 AST 的每个节点,每碰到一个节点就检查有没有匹配的规则。
  3. 报告 :匹配到规则后,根据规则配置(off / warn / error)输出对应级别的诊断信息。

插件 提供规则,配置 决定哪些规则开启、开到什么级别。这就是 ESLint "插件 + 配置" 的设计哲学。


快速上手

安装

bash 复制代码
npm install -D eslint

初始化配置

bash 复制代码
npx eslint --init

ESLint 会问你几个问题(项目类型、框架、是否用 TypeScript 等),然后生成 .eslintrc.js

js 复制代码
// .eslintrc.js --- 旧版配置格式(eslintrc)
module.exports = {
  env: {
    browser: true,
    es2021: true,
    node: true,
  },
  extends: 'eslint:recommended',
  parserOptions: {
    ecmaVersion: 2021,
    sourceType: 'module',
  },
  rules: {
    'no-unused-vars': 'warn',
    'no-console': 'warn',
    'eqeqeq': 'error',
    'prefer-const': 'error',
  },
};

新版配置格式(Flat Config)

ESLint 9+ 默认使用扁平化配置 eslint.config.js

js 复制代码
// eslint.config.js
import js from '@eslint/js';

export default [
  js.configs.recommended,
  {
    rules: {
      'no-unused-vars': 'warn',
      'no-console': 'warn',
      'eqeqeq': 'error',
    },
  },
];

扁平配置用数组代替继承链,更直观、更容易理解每条规则从哪来。

运行

bash 复制代码
# 检查所有文件
npx eslint .

# 检查并自动修复
npx eslint . --fix

# 只检查特定文件
npx eslint src/**/*.js

配合 npm scripts

json 复制代码
{
  "scripts": {
    "lint": "eslint .",
    "lint:fix": "eslint . --fix"
  }
}

常用规则速查

错误检测类

js 复制代码
rules: {
  'no-unused-vars': 'error',      // 声明但未使用的变量
  'no-undef': 'error',            // 使用未定义的变量
  'no-unreachable': 'error',      // return 后的不可达代码
  'no-cond-assign': 'error',      // 条件语句中出现赋值
  'no-debugger': 'error',         // debugger 语句
}

风格规范类

js 复制代码
rules: {
  'indent': ['error', 2],              // 统一缩进 2 空格
  'quotes': ['error', 'single'],       // 统一单引号
  'semi': ['error', 'always'],         // 强制分号
  'no-trailing-spaces': 'error',       // 禁止行尾空格
  'eol-last': 'error',                 // 文件末尾空行
}

最佳实践类

js 复制代码
rules: {
  'eqeqeq': 'error',              // 必须用 === 而非 ==
  'no-eval': 'error',             // 禁止 eval
  'no-var': 'error',              // 禁止 var
  'prefer-const': 'error',        // 优先用 const
  'no-multiple-empty-lines': ['error', { max: 2 }],
}

建议:风格类规则交给 Prettier 处理,ESLint 专注代码质量和最佳实践,两者各司其职。后面会展开说。


与 Prettier 的关系

很多人搞不清 ESLint 和 Prettier 的区别,简单说:

ESLint Prettier
关注什么 代码质量 + 代码风格 纯代码格式化
典型问题 未使用的变量、== vs ===、不可达代码 缩进、引号、换行、行宽
能修复逻辑吗 能发现问题,部分能自动修复 不能,只改格式不改逻辑
能配规则吗 能,几百条 几乎不能,只有几个选项

最佳实践:两者一起用。

  • ESLint 负责"代码对不对"
  • Prettier 负责"代码好不好看"
  • eslint-config-prettier 关闭 ESLint 中与 Prettier 冲突的格式化规则
bash 复制代码
npm install -D prettier eslint-config-prettier
js 复制代码
// .eslintrc.js
module.exports = {
  extends: [
    'eslint:recommended',
    'prettier',  // 放最后,关闭冲突的格式规则
  ],
};

TypeScript 项目怎么配?

TypeScript 项目需要额外的解析器和插件:

bash 复制代码
npm install -D @typescript-eslint/parser @typescript-eslint/eslint-plugin
js 复制代码
// eslint.config.js
import js from '@eslint/js';
import tseslint from 'typescript-eslint';

export default tseslint.config(
  js.configs.recommended,
  ...tseslint.configs.recommended,
  {
    rules: {
      '@typescript-eslint/no-unused-vars': 'warn',
      '@typescript-eslint/no-explicit-any': 'warn',
    },
  },
);

@typescript-eslint 能检查类型层面的错误,比如:

  • 显式使用 any 类型(no-explicit-any
  • 非空断言 ! 滥用(no-non-null-assertion
  • 不安全的类型断言(no-unsafe-assertion

配合 Git Hook 自动化

最理想的状态是:代码提交前自动检查,不合格的代码根本进不了仓库。

用 lint-staged + husky

bash 复制代码
npm install -D husky lint-staged
npx husky init
json 复制代码
// package.json
{
  "scripts": {
    "prepare": "husky"
  },
  "lint-staged": {
    "*.{js,ts,jsx,tsx}": "eslint --fix"
  }
}
bash 复制代码
echo "npx lint-staged" > .husky/pre-commit

这样每次 git commit 时,ESLint 会自动检查暂存区的文件,有问题就阻止提交。只有新增/修改的文件会被检查,不会全量扫描,速度很快。


常见配置预设

与其从零配置,不如站在巨人肩膀上。社区提供了很多成熟的配置预设:

预设 特点
eslint:recommended ESLint 官方推荐,覆盖最常见的错误检测
eslint-config-airbnb Airbnb 的严格风格规范,曾经是社区标准
eslint-config-standard 标准风格,无分号、无冗余配置
eslint-config-next Next.js 官方配置,包含 React + a11y 规则
eslint-config-react-app CRA 内置配置
eslint-config-prettier 关闭与 Prettier 冲突的规则
js 复制代码
// 组合使用
export default [
  js.configs.recommended,
  ...reactHooks.configs.recommended,
  ...reactRefresh.configs.vite,
  prettierConfig,  // 放最后
];

总结

ESLint 解决的核心问题:让错误尽早暴露、让风格保持一致、让最佳实践成为习惯。

不用 ESLint 用 ESLint
Bug 到运行时才暴露 写代码时就发现
Code Review 在争论分号 Code Review 聚焦逻辑
每个人代码风格不同 团队代码如同出自一人
新人不了解最佳实践 规则本身就是文档和教学

如果你还没在项目里用 ESLint,现在就装一个吧:

bash 复制代码
npm install -D eslint
npx eslint --init

你的代码库会感谢你。

相关推荐
子兮曰2 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰2 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万2 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝2 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
胡写代码2 天前
别再前后端各写一套表单校验了
java·后端
三十而立洋2 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
大勇前进2 天前
原生 PHP 还是 Laravel?小项目到底要不要上框架
后端
yuzhi_liu2 天前
我用 LangGraph4j 实现 Multi-Agent Supervisor
后端
alsmile2 天前
Node-RED 之外,国产规则引擎的新方案:基于标准语法,Go 先行实现
后端·开源·go
大白802 天前
PHP 内存溢出排查思路:看懂报错日志,精准定位问题
后端