代码开发,规范很重要------但"重要"不解决任何问题,把它变成强制执行的闸门才是关键。ESLint 就是这道闸门。
从一个练习文件说起
我在练习目录建了一个 index.mjs,装好 ESLint,配好规则后跑了 pnpm lint:
js
// index.mjs ------ 被 ESLint 检查的练习文件
//let name="lxk";
function hello(){
//console.log(name+"hello");
}
hello();
输出干干净净,一行报错都没有------因为它符合我配置的规范。这给了我一个直观的感受:规范这种东西,只要配置好了,机器会替你把关,不用人肉检查。
这篇文章就是我从零理解 ESLint 的完整笔记:它是什么、能带来什么价值、怎么配、怎么用。
一、ESLint 是什么
一句话:ESLint 是静态代码检查工具(Lint 工具)。
它的工作方式很特殊------它不运行你的代码,而是像"语文老师批作文"一样,逐行读你的源码,对照你定义的规则(规范)找毛病。
它之所以叫"开发依赖"(devDependencies),是因为它只在开发时起作用,不会打进上线的代码里。
它的核心机制是三部分配合:
scss
规则库(定义哪些算违规) + 配置文件(规则开关和参数) + 检查器(读源码 → 对照规则 → 报告)
规则是"标准",配置是"你要用哪些标准、怎么用",检查器是"执行的人"。
二、配置的第一课:["error", "double"] 是什么
ESLint 的规则配置有个通用格式,用数组表示时两个参数分工不同:
js
rules: {
"quotes": ["error", "double"]
}
第一个参数:违规等级(所有规则都有)
| 值 | 含义 |
|---|---|
0 / "off" |
关闭这条规则 |
1 / "warn" |
警告(黄色,不阻断通过) |
2 / "error" |
错误(红色,直接不通过) |
第二个参数:规则自己的选项(按规则而定)
这个参数每条规则不一定有、含义也不同 。对 quotes 来说,它指定"要求哪种引号":
"double"→ 字符串必须用双引号"single"→ 必须用单引号"backtick"→ 必须用反引号
所以 ["error", "double"] 连起来读就是:"双引号规则强制开启,违规报错,字符串一律用双引号"。
对照我配置里的另外几条,正好展示了"等级 + 选项"的完整模式:
js
"quotes": ["error", "double"], // 等级=error(必须双引号),选项=double
"semi": ["error", "always"], // 等级=error,选项=always(必须加分号)
"indent": ["error", 2], // 等级=error,选项=2(缩进 2 空格)
"no-var": 2 // 没有第二个参数,因为它没有可调选项
一条经验:规则配置 = 等级(必有)+ 规则专属选项(可选) 。没有选项的规则,直接写
2就行。
三、它到底带来了什么价值
1. 对个人:把错误拦在"最便宜的阶段"
软件里修 bug 的成本,越晚发现越贵:
写代码时发现 → 编辑器报错 → 提交前 → CI → 测试 → 上线后
最便宜 ────────────────────────────────────────→ 最贵
ESLint 工作在最左边 。我开启的 js/recommended 是官方推荐规则集,专门抓真实 bug:
js
// no-undef: 变量名拼错,用了没定义的
consoe.log("hi"); // ❌ 拼错了,运行时不报错、静默失效
// eslint 会在写代码时就告诉你:consoe is not defined
// no-unused-vars: 声明了不用,大概率逻辑断了
let total = 0;
total = total + price; // 后面再也没用过 total
// no-constant-condition: 永远为真的分支 → 死代码
if (true) { ... }
这些 bug 运行时不会崩、测试未必测到,等到上线后出问题,排查成本极高。而 ESLint 在写下的瞬间就标红了。
2. 对团队:让"规范"从口头约定变成强制执行
没有工具时,团队规范靠 review 时人肉提醒,效果很差:新人不知道规范、review 一半精力在吵"该不该加分号"、git diff 里全是格式噪音。
有了 ESLint,规范变成机器强制:
no-var→ 统一let/const,避开var的变量提升坑quotes+semi+indent→ 全队代码长得一样,diff 干净,review 只谈逻辑
人的自觉 + 机器强制,是本质区别------机器不会"今天心情不好就不检查"。
3. 对项目:形成"防劣化"的自动关卡
代码库在长期迭代中天然容易腐烂。一条完整的链路可以把劣化拦在源头:
ruby
编辑器实时标红(写完立刻知道)
↓
git 提交钩子(pre-commit):eslint 不过,不许提交
↓
CI 流水线:eslint 不过,合并请求不通过
每次变更都被卡一次,烂代码进不了代码库。
四、实战:在一个项目里落地 ESLint
第 1 步:安装
bash
pnpm add -D eslint @eslint/js globals
eslint:检查器本体@eslint/js:官方推荐规则包(提供js/recommended)globals:预置的全局变量表(globals.node、globals.browser)
第 2 步:配置文件
完整配置长这样:
js
// eslint.config.mjs
import js from "@eslint/js";
import globals from "globals";
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: ["**/*.{js,mjs,cjs}"], // 作用范围
plugins: { js }, // 插件
extends: ["js/recommended"], // 继承预设规则集
languageOptions: { globals: globals.node }, // 语言环境
rules: { // 自定义规则
"no-var": 2,
"no-console": 1,
"quotes": ["error", "double"],
"semi": ["error", "always"],
"indent": ["error", 2]
}
}
]);
第 3 步:配置 scripts
json
"scripts": {
"lint": "eslint .", // 只检查
"lint:fix": "eslint . --fix" // 检查 + 自动修复能修的
}
eslint . 里的 . 表示检查整个目录。
第 4 步:编辑器集成(体验的关键)
装 VSCode 的 ESLint 插件,开启"保存自动修复":
json
{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
}
}
这样不用跑命令,一写一存就实时标红并自动修。
第 5 步(可选):git 提交钩子 + CI
配合 husky + lint-staged 做"提交前自动 lint",再在 CI 里加一步 pnpm lint,就形成了完整的自动关卡。
小结:个人用 → 前 4 步;团队正式项目 → 全部 6 步。
五、一份配置由哪几类东西组成
一份 ESLint 配置由 5 类东西拼成:
| 类别 | 作用 | 常见例子 |
|---|---|---|
① files / ignores |
声明规则作用于哪些文件 | files: ["src/**/*.js"] |
② plugins |
引入第三方规则集合 | @typescript-eslint、react、vue |
③ extends |
继承现成规则集 | js/recommended、airbnb、standard |
④ languageOptions |
告诉 ESLint 用哪种语法、有哪些全局变量 | globals: globals.browser |
⑤ rules |
亲手开关和调参每条规则 | "no-var": 2 |
一条关键心智模型:
plugins是"规则仓库",extends是"直接拿来用的成品包",rules是"在成品上再微调"。
所以常见写法是 extends 套一个大包,再用 rules 覆盖其中几条。TS / Vue / React 项目还会再加 parser(让 ESLint 能解析新语法)和 settings。
六、基本语法速查表
1. 规则的三种写法
js
rules: {
"no-var": 2, // 只有等级
"quotes": "error", // 只有等级(字符串形式)
"semi": ["error", "always"], // [等级, 选项1, 选项2...]
}
2. 等级:数字和字符串等价
| 数字 | 字符串 | 含义 |
|---|---|---|
0 |
"off" |
关闭 |
1 |
"warn" |
警告 |
2 |
"error" |
错误 |
3. 代码里临时豁免
js
// eslint-disable-next-line no-console
console.log("就这一行放行");
/* eslint-disable no-var */ // 从这往下关闭 no-var
var a = 1;
/* eslint-enable no-var */ // 恢复
4. 命令行常用参数
bash
eslint . # 检查当前目录
eslint src/index.js # 只检查单个文件
eslint . --fix # 检查并自动修复
eslint --print-config index.js # 打印某文件最终生效的全部规则(debug 神器)
七、结语
ESLint 是"代码质量的闸门 ":个人层面拦截低级错误、团队层面统一规范、工程层面守住质量底线。它不提高你的智商,但保证下限------让烂代码进不了代码库,让你省下的精力都花在逻辑上。
入门阶段用熟这四样就够吃透它:["error", "选项"] 的参数含义、Flat Config 的五大件、scripts + 编辑器实时检查、规则语法速查 。至于框架项目里的 @typescript-eslint、eslint-plugin-react、husky 钩子,都是在这套心智模型上长出来的枝叶。