一、什么是 ESLint
ESLint 是一个开源的 JavaScript/TypeScript 代码检查工具,由 Nicholas C. Zakas 于 2013 年创建。它的核心作用是在代码运行之前,自动发现并报告代码中的语法错误、风格问题和潜在缺陷。
为什么需要 ESLint
- 统一代码风格:团队成员写出格式一致的代码,减少 review 中的"格式争议"
- 提前发现 Bug:未使用的变量、隐式类型转换、空函数引用等问题在编写阶段就被拦截
- 约束最佳实践:禁止
var、强制===、限制console在生产环境的残留 - 与编辑器集成:在 VSCode 等 IDE 中实时标红问题代码,写代码时就能获得反馈
ESLint vs Prettier
很多人会混淆两者。简单来说:
| 工具 | 侧重点 | 典型问题 |
|---|---|---|
| ESLint | 代码逻辑和质量 | 未使用变量、隐式全局变量、== 比较 |
| Prettier | 纯格式化 | 缩进、引号、换行位置 |
两者可以配合使用:ESLint 负责逻辑检查,Prettier 负责格式化。但在简单项目中,也可以只用 ESLint 的格式规则来统一风格。
二、ESLint 在项目中的位置
在一个典型的前端项目中,ESLint 处于开发时质量保障链的核心位置:
项目目录结构
├── src/ # 源代码
│ ├── utils/
│ ├── components/
│ └── App.ts
├── eslint.config.js ← ESLint 配置文件(项目根目录)
├── package.json # 依赖与脚本
├── tsconfig.json # TypeScript 配置
└── .vscode/
└── settings.json # 编辑器集成配置
它的协作关系
开发者写代码
│
▼
┌───────────┐ 实时提示 ┌───────────┐
│ 编辑器 │ ◄──── ESLint ────│ ESLint │
│ (VSCode) │ │ 引擎 │
└─────┬─────┘ └─────┬─────┘
│ │
▼ ▼
┌───────────┐ 提交触发 ┌───────────┐
│ Git Hook │ ◄──── (lint- │ CI/CD │
│ (husky) │ staged) │ Pipeline │
└───────────┘ └───────────┘
ESLint 在项目中有三个层面的介入:
- 编辑器层面:通过 VSCode ESLint 插件,写代码时实时标红和提示
- Git Hook 层面:配合 husky + lint-staged,提交代码前自动检查暂存区文件
- CI/CD 层面:在流水线中全量扫描,确保合并到主分支的代码符合规范
三、配置文件详解(代码示例)
以下是一个完整的 eslint.config.js(ESLint Flat Config 格式,v9+):
import js from "@eslint/js";
import globals from "globals";
import tseslint from "typescript-eslint";
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: ["**/*.{js,mjs,cjs,ts,mts,cts}"],
plugins: { js },
extends: ["js/recommended"],
languageOptions: {
globals: globals.browser
},
rules: {
"no-var": 2, // 禁止使用 var,必须用 let/const
"no-console": 1, // 警告:开发可用,上线前应移除
"quotes": ["error", "double"], // 必须使用双引号
"semi": ["error", "always"], // 语句末尾必须加分号
"indent": ["error", 2], // 缩进必须为 2 个空格
}
},
tseslint.configs.recommended,
]);
逐行解析
1. 导入依赖
import js from "@eslint/js"; // ESLint 官方推荐的 JS 规则集
import globals from "globals"; // 预定义的全局变量环境(browser、node 等)
import tseslint from "typescript-eslint"; // TypeScript ESLint 适配
import { defineConfig } from "eslint/config"; // ESLint 配置辅助函数
2. 配置块结构
ESLint Flat Config 是一个数组,每个元素是一个配置对象:
{
files: ["**/*.{js,mjs,cjs,ts,mts,cts}"], // 匹配的文件范围
plugins: { js }, // 注册插件
extends: ["js/recommended"], // 继承推荐规则集
languageOptions: {
globals: globals.browser // 声明全局环境:浏览器环境
},
rules: { ... } // 自定义规则覆盖
}
files:只对这些后缀的文件生效,其他文件不受影响extends: ["js/recommended"]:直接使用官方推荐的规则集(约 50+ 条规则)globals: globals.browser:告诉 ESLintwindow、document、fetch等是合法的浏览器全局变量,不会报未定义错误
3. 规则配置
规则值的含义:
| 值 | 含义 | 效果 |
|---|---|---|
0 或 "off" | 关闭 | 不检查 |
1 或 "warn" | 警告 | 黄色波浪线,不阻断 |
2 或 "error" | 错误 | 红色波浪线,会阻断提交和 CLI 退出码 |
rules: {
"no-var": 2, // 错误:禁止 var
"no-console": 1, // 警告:console 可用但提醒移除
"quotes": ["error", "double"], // 错误:必须双引号
"semi": ["error", "always"], // 错误:必须加分号
"indent": ["error", 2], // 错误:必须 2 空格缩进
}
4. TypeScript 支持
tseslint.configs.recommended,
这一行让 ESLint 具备检查 TypeScript 文件的能力,包括类型导入、非空断言、未使用类型等 TS 特有规则。
对应的错误代码示例
// ❌ no-var
var name = "test"; // 报错:应使用 let 或 const
// ❌ quotes
const str = 'hello'; // 报错:应使用双引号 "hello"
// ❌ semi
const x = 1 // 报错:缺少分号
// ❌ indent
function test() {
return true; // 报错:应缩进 2 空格,不是 4 空格
}
// ⚠️ no-console
console.log("debug"); // 警告:生产环境应移除
// ✅ 正确写法
const name = "test";
const str = "hello";
const x = 1;
function test() {
return true;
}
四、终端使用指南
1. 初始化 ESLint
在项目根目录执行:
# 初始化配置(交互式选择框架和规则)
npx eslint --init
# 或手动安装依赖
npm install -D eslint @eslint/js globals typescript-eslint
2. 扫描整个项目
# 扫描当前目录下所有匹配的文件
npx eslint .
# 扫描指定目录
npx eslint src/
# 扫描指定文件
npx eslint src/utils/helper.ts
# 扫描特定文件类型
npx eslint "src/**/*.ts"
扫描输出示例
$ npx eslint .
1:5 error 'unused' is defined but never used no-unused-vars
3:1 error Unexpected var, use let or const no-var
5:10 warning Unexpected console statement no-console
7:15 error Strings must use doublequote quotes
8:1 error Missing semicolon semi
✖ 4 problems (3 errors, 1 warning)
1 error and 0 warnings potentially fixable with the `--fix` option.
输出格式说明:
1:5— 文件第 1 行第 5 列error/warning— 问题级别- 规则名称(如
no-unused-vars)— 可以在配置中关闭或调整
3. 自动修复
ESLint 能自动修复一部分问题(主要是格式类规则,如引号、分号、缩进):
# 自动修复所有可修复的问题
npx eslint . --fix
# 只修复,不报告未修复的问题
npx eslint . --fix --quiet
哪些规则可以自动修复
| 规则 | 可自动修复 | 说明 |
|---|---|---|
quotes | ✅ | 自动把单引号改为双引号 |
semi | ✅ | 自动补分号 |
indent | ✅ | 自动调整缩进 |
no-var | ❌ | 需要判断用 let 还是 const,无法自动 |
no-console | ❌ | 无法判断是否应该删除,需手动处理 |
no-unused-vars | ❌ | 无法判断变量是否需要保留,需手动处理 |
提示:
--fix只修复确定性规则。涉及语义判断的规则(如未使用变量、禁止 var)无法自动修复,需要开发者手动处理。
4. 输出格式控制
# JSON 格式(适合 CI/CD 解析)
npx eslint . --format json
# HTML 报告(生成可视化报告)
npx eslint . --format html --output-file eslint-report.html
# 紧凑格式(每行一个问题)
npx eslint . --format compact
# 不输出颜色(适合日志文件)
npx eslint . --no-color
5. 配合 package.json 脚本
在 package.json 中添加脚本,方便日常使用:
{
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"lint:src": "eslint src/",
"lint:report": "eslint . --format html --output-file eslint-report.html"
}
}
使用方式:
npm run lint # 扫描整个项目
npm run lint:fix # 自动修复
npm run lint:src # 只扫描 src 目录
npm run lint:report # 生成 HTML 报告
6. 配合 Git Hook(提交前自动检查)
安装 husky 和 lint-staged:
npm install -D husky lint-staged
npx husky init
在 .husky/pre-commit 中写入:
npx lint-staged
在 package.json 中配置 lint-staged:
{
"lint-staged": {
"*.{js,mjs,cjs,ts,mts,cts}": [
"eslint --fix"
]
}
}
这样每次 git commit 时,只会对暂存区的文件执行 ESLint 检查和自动修复,如果存在无法修复的错误,提交会被阻断。
五、总结
| 场景 | 命令 | 说明 |
|---|---|---|
| 写代码时 | 编辑器 ESLint 插件 | 实时标红,无需手动运行 |
| 手动扫描 | npx eslint . | 全量检查项目 |
| 自动修复 | npx eslint . --fix | 修复格式类问题 |
| 提交前检查 | husky + lint-staged | 只检查暂存区文件 |
| CI/CD | npx eslint . --format json | 输出机器可读格式 |
ESLint 的核心价值在于:把代码质量的把关从"人来 review"前移到"工具自动检查",在代码编写阶段就消灭大部分低级错误和风格不一致问题。配置好一次,整个团队持续受益。