ESLint 到底在帮我们守住什么?从规则配置到工程实践

ESLint 到底在帮我们守住什么?从规则配置到工程实践

前面的课我们一直在写代码------前端组件、后端接口、全栈框架。代码能跑就行了吗?

这节课换一个角度:不写新功能,而是给代码立规矩。

工具就一个:ESLint。它干的事一句话能说清------强制团队写出一致风格的代码,严格检查代码,找出潜在的 bug。

一、ESLint 是什么:代码工程质量的底线

先看关于 eslint 的定位:

eslint 是代码工程质量的重要保证,强制团队写出一致风格的代码,可以严格检查代码,找出潜在的 bug

三个关键词:一致风格 、严格检查 、找潜在 bug。

"一致风格"不是审美问题。两个人写代码,一个用 var,一个用 let;一个两空格缩进,一个四空格缩进;一个加分号,一个不加分号------代码能跑,但合并的时候冲突多到爆炸,review 的时候光看风格就累死了。

eslint 添加一些约束规则

ESLint 的做法是:你把规则定好,它替你盯着。 违反规则的代码,要么报警告,要么直接报错不让提交。

二、安装与项目结构

从 package.json 看整个项目的依赖和脚本:

json 复制代码
{
  "name": "eslint-demo",
  "version": "1.0.0",
  "description": "eslint 是代码工程质量的重要保证,强制团队写出一致风格的代码,可以严格检查代码,找出潜在的 bug",
  "main": "index.js",
  "scripts": {
    "lint": "eslint .", 
    "lint:fix": "eslint . --fix",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "type": "commonjs",
  "devDependencies": {
    "@eslint/js": "^10.0.1",
    "eslint": "^10.8.1",
    "globals": "^17.11.0",
    "typescript-eslint": "^8.67.0"
  }
}

几个要点:

  1. eslint 放在 devDependencies ------ 它是开发工具,不是运行时依赖,生产环境不需要。
  2. 两个脚本 :
    • "lint": "eslint ." ------ 检查当前目录下所有文件
    • "lint:fix": "eslint . --fix" ------ 检查并自动修复能修的(比如引号、分号、缩进)
  3. 四个 devDependencies ,每个都有用:
    • @eslint/js ------ ESLint 官方推荐的 JS 规则集
    • eslint ------ ESLint 本体
    • globals ------ 预定义的全局变量环境
    • typescript-eslint ------ TypeScript 的 ESLint 解析器和规则

运行 npm run lint 就是 eslint .,检查所有文件。运行 npm run lint:fix 就是 eslint . --fix,能自动修的就帮你修了。

三、配置文件:flat config 长什么样

ESLint 9+ 用的是 flat config------配置文件叫 eslint.config.mjs,不再是老的 .eslintrc。我的配置:

javascript 复制代码
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.node },
    rules: {
      // 2=error 表示必须遵守,也就是错误,1=warn 表示警告,0=off 表示关闭
      "no-var": 2,// 不能用 var 声明变量
      "no-console": 1,// 1,开发阶段允许使用,但是上线之后不用 不能用 console 打印
      "quotes": ["error", "double"],// 双引号
      "semi": ["error", "always"],// 语句末尾有分号
      "indent": ["error", 2],// 缩进 2 个空格
    }
  },
  tseslint.configs.recommended,
]);

逐块拆开看。

3.1 四个 import

javascript 复制代码
import js from "@eslint/js";
import globals from "globals";
import tseslint from "typescript-eslint";
import { defineConfig } from "eslint/config";
  • @eslint/js :ESLint 官方的 JS 规则包,提供 js/recommended 推荐规则集。
  • globals :预定义全局变量集合。比如 globals.node 包含 require、module、process 等 Node.js 环境的全局变量,globals.browser 包含 window、document 等。没有它,ESLint 会对这些全局变量报 "no-undef"。
  • typescript-eslint:让 ESLint 能理解 TypeScript 语法,同时提供 TS 专属规则。
  • defineConfig:ESLint 提供的配置辅助函数,提供类型提示。

3.2 files:规则对哪些文件生效

javascript 复制代码
files: ["**/*.{js,mjs,cjs,ts,mts,cts}"]

匹配所有 .js、.mjs、.cjs、.ts、.mts、.cts 文件。** 是递归匹配,子目录里的也算。

3.3 extends:继承推荐规则

javascript 复制代码
plugins: { js }, 
extends: ["js/recommended"],

plugins: { js } 注册插件,extends: ["js/recommended"] 继承官方推荐规则集。推荐规则集里已经包含了几十条最佳实践规则,比如禁止使用 eval、禁止重复声明等。不用一条条自己写。

3.4 languageOptions:全局环境

javascript 复制代码
languageOptions: { globals: globals.node },

告诉 ESLint:这段代码跑在 Node.js 环境。process、require、__dirname 这些 Node 全局变量不会报 "no-undef"。如果代码跑在浏览器,换成 globals.browser。

3.5 rules:6 条自定义规则

这是配置的核心。先看规则严重级别的约定:

2=error 表示必须遵守,也就是错误,1=warn 表示警告,0=off 表示关闭

也可以写成字符串:"error"、"warn"、"off"。数字和字符串等价。

6 条规则逐条看:

规则 值 含义
no-var 2(error) 不能用 var 声明变量,必须用 let 或 const
no-console 1(warn) 开发阶段允许使用,但上线之后不用 console 打印
quotes ["error", "double"] 必须用双引号
semi ["error", "always"] 语句末尾必须有分号
indent ["error", 2] 缩进 2 个空格

有几种写法值得注意:

  1. "no-var": 2 ------ 直接一个数字,表示 error 级别。没有额外参数。
  2. "no-console": 1 ------ warn 级别。允许你写,但会提醒你:上线前记得删。
  3. "quotes": ["error", "double"] ------ 数组形式。第一个是严重级别,第二个是参数值。这里要求双引号。
  4. "semi": ["error", "always"] ------ 同样是数组。"always" 表示总是要分号。
  5. "indent": ["error", 2] ------ 缩进必须 2 个空格,不是 tab。

注意 "no-var": 2 和 "quotes": ["error", "double"] 是两种写法------数字和字符串 "error" 等价。正式项目里建议统一用字符串,可读性更好。

3.6 tseslint.configs.recommended

javascript 复制代码
tseslint.configs.recommended,

这一行在 defineConfig 数组的第二个位置,和第一个对象是并列的。它给 TypeScript 文件额外加了一套推荐规则------类型检查、TS 语法相关的最佳实践。

这种"数组里放多个配置对象"的方式是 flat config 的核心特性:每个对象管自己的 files,互不干扰。

四、被检查的代码:6 行代码能踩几个坑

index.mjs 是被检查的目标文件:

javascript 复制代码
let name = "lk_ai";
// let a = 1;

function hello() {
  console.log("hello " + name);
}
hello();

拿我们的规则跑一遍,看看会怎样:

  1. no-var ✅ 没有 var,用的是 let,通过。
  2. no-console ⚠️ console.log("hello " + name) 触发警告------开发可以用,但提醒你上线前处理掉。
  3. quotes ✅ 双引号,通过。
  4. semi ✅ 每行末尾都有分号,通过。
  5. indent ✅ 函数体缩进 2 个空格,通过。

注释 // let a = 1; 被注释掉了,不检查。

这段代码基本守规矩。如果把 let name 改成 var name,no-var 规则会直接报 error。如果改成单引号 'lk_ai',quotes 规则也报 error。这就是 ESLint 替你盯着的效果。

五、lint 和 lint:fix:检查和自动修复

两个脚本的区别很重要:

text 复制代码
npm run lint       → eslint .
                      检查所有文件,列出所有 error 和 warn,不改动代码

npm run lint:fix   → eslint . --fix
                      检查并自动修复能修的(引号、分号、缩进等),
                      修不了的(比如 no-var 需要你判断用 let 还是 const)仍然报出来

--fix 不是万能的。风格类的规则(引号、分号、缩进)能自动改;但逻辑类的规则(比如 no-var 要你决定用 let 还是 const,no-console 要你决定删还是保留)只能提醒,不敢自动改。

我现在怎么理解这节课

这节课之前,我对 ESLint 的印象就是"编辑器里飘红线的那个东西"。配置文件打开看不懂,全是规则名,也不知道每个数字什么意思。

拆开配置以后,ESLint 的逻辑其实很直白:

text 复制代码
定规则 → 检查代码 → 违反就报 error 或 warn → 能自动修的用 --fix

其中最关键的是三条严重级别:2=error 必须遵守,1=warn 警告,0=off 关闭。记住这一条,配置文件就能读个大概了。

更大的认知转变是:ESLint 不只是"查风格"。extends: ["js/recommended"] 里包含了几十条最佳实践规则,能帮你找到潜在的 bug------比如未使用的变量、重复声明、不安全的比较。风格只是它的一部分能力,找 bug 才是它更值钱的那部分。

回到 Vibe Coding 时代,ESLint 变得更重要了。AI 写代码很快,但它不会管你的项目用双引号还是单引号、用 var 还是 let。把 ESLint 配好,AI 写出来的代码过一遍 lint,风格不一致的地方立刻暴露。--fix 能自动修掉一大半,省下来的时间去看真正的逻辑问题。

这节课教的不是某个 API,而是一种工程思维 :代码能跑只是及格线,团队一致、风格统一、潜在 bug 被提前拦住,才是工程质量的底线。

术语速查

  • ESLint:JavaScript/TypeScript 代码检查工具,通过自定义规则检查代码风格和潜在问题。
  • flat config :ESLint 9+ 的新配置格式,配置文件为 eslint.config.mjs,用数组组织多个配置对象,替代了旧的 .eslintrc。
  • 规则严重级别 :2 或 "error" 表示报错(必须遵守),1 或 "warn" 表示警告,0 或 "off" 表示关闭。数字和字符串等价。
  • extends(继承) :继承一套预设规则集,不用逐条手写。比如 js/recommended 是 ESLint 官方推荐的 JS 规则集。
  • plugins(插件):注册一个规则包,注册后才能 extends 它的规则集。
  • globals 包 :预定义各运行环境的全局变量集合。globals.node 包含 Node.js 全局变量(require、module、process),globals.browser 包含浏览器全局变量(window、document)。
  • typescript-eslint:让 ESLint 理解 TypeScript 语法的解析器 + 规则集,提供 TS 专属的类型检查规则。
  • --fix :ESLint 的自动修复参数,能自动修正风格类问题(引号、分号、缩进),但不能修逻辑类问题(如 no-var 需要人工判断用 let 还是 const)。
  • devDependencies:开发依赖,只在开发阶段使用,生产环境不需要。ESLint 作为代码检查工具,放在 devDependencies。
相关推荐
这个DBA有点耶5 小时前
ELT 工具选型完整指南:从 ETL 差异分析到工程落地
数据库·架构·代码规范
这个DBA有点耶6 小时前
分布式事务深度:TCC空回滚、悬挂与Saga补偿风暴的根因与解法
数据库·mysql·代码规范
这个DBA有点耶2 天前
为什么UPDATE比SELECT危险得多?锁范围等于扫描行数
数据库·架构·代码规范
沈麽鬼2 天前
纸上代码
代码规范
深圳老胡4 天前
STM32CubeMX 生成 CMake 工程,用 VSCode 编译与调试的完整流程
笔记·stm32·单片机·代码规范
星星泡饭吃4 天前
【信息安全】越权防护设计评审指南
代码规范
GlobalSign数字证书5 天前
申请 EV 代码签名证书需要准备哪些材料?
代码规范
深圳老胡5 天前
STM32F4 OTA 升级双 App 方案设计与实现
笔记·stm32·单片机·代码规范
深圳老胡5 天前
STM32F4 OTA升级:单App与双App方案优缺点对比
笔记·stm32·单片机·代码规范
这个DBA有点耶5 天前
Change Buffer深入:二级索引写入的隐形加速器与它的代价
数据库·mysql·代码规范