ESLint 从零到落地:把"代码规范"变成机器的强制检查

代码开发,规范很重要------但"重要"不解决任何问题,把它变成强制执行的闸门才是关键。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 钩子,都是在这套心智模型上长出来的枝叶。

相关推荐
浮链序10 小时前
Shopify 把 10 亿商品开放给任意 agent 了:我用零依赖 Python 撸了个带预算闸门的代购网关
后端·代码规范
这个DBA有点耶1 天前
ELT 工具选型完整指南:从 ETL 差异分析到工程落地
数据库·架构·代码规范
这个DBA有点耶1 天前
分布式事务深度:TCC空回滚、悬挂与Saga补偿风暴的根因与解法
数据库·mysql·代码规范
这个DBA有点耶3 天前
为什么UPDATE比SELECT危险得多?锁范围等于扫描行数
数据库·架构·代码规范
沈麽鬼3 天前
纸上代码
代码规范
深圳老胡5 天前
STM32CubeMX 生成 CMake 工程,用 VSCode 编译与调试的完整流程
笔记·stm32·单片机·代码规范
星星泡饭吃6 天前
【信息安全】越权防护设计评审指南
代码规范
GlobalSign数字证书6 天前
申请 EV 代码签名证书需要准备哪些材料?
代码规范
深圳老胡6 天前
STM32F4 OTA 升级双 App 方案设计与实现
笔记·stm32·单片机·代码规范
深圳老胡6 天前
STM32F4 OTA升级:单App与双App方案优缺点对比
笔记·stm32·单片机·代码规范