ESLint 与 Prettier
ESLint 负责"查错误与坏味道",Prettier 负责"统一格式"。两者一个管质量、一个管风格,是现代前端工程的标配双剑。本文从原理到实战,把配置链路完整走一遍。
一、ESLint 作用与原理
ESLint 是 JavaScript 的静态代码检查工具,在代码运行前发现潜在问题。
1.1 原理:AST 检查
ESLint 先把源码解析成 AST(抽象语法树),然后让规则插件遍历 AST 节点,检查是否违反规则:
源码字符串
→ 解析器(espree 等)生成 AST
→ 规则遍历 AST 节点并报告问题
→ 输出错误/警告,可自动修复(--fix)// 一段代码会被解析为带类型和位置的节点树
function greet(name) {
return "hi " + name;
}
// → AST: Program → FunctionDeclaration → params[0](Identifier: name)...因为是结构化检查,ESLint 能发现 typeof x === "undefined" 之类的深层问题,也能自动修复(--fix)绝大多数简单问题。
二、安装与初始化
npm install -D eslint
npx eslint --init # 交互式生成配置文件
npx eslint src/ # 检查目录
npx eslint src/ --fix # 自动修复可修复问题新版本也可用扁平配置(eslint.config.js),经典配置为 .eslintrc.js(.eslintrc/.eslintrc.json 亦可):
npx eslint --init
# 选择:检查语法 + 问题 + 强制代码风格 → ES Modules → Vue/React → TypeScript → 浏览器环境三、.eslintrc 配置详解
// .eslintrc.js
module.exports = {
root: true, // 停止向上查找父目录配置
env: {
browser: true, // 浏览器全局变量(window、document 等)
es2022: true, // 支持 ES2022 全局与语法
node: true, // Node 全局变量(require、process 等)
},
parser: "@typescript-eslint/parser", // 解析器:把 TS 语法解析成可检查的 AST
parserOptions: {
ecmaVersion: "latest",
sourceType: "module",
ecmaFeatures: { jsx: true },
},
plugins: ["@typescript-eslint", "vue"], // 提供额外规则集的插件
extends: [ // 继承共享配置(后面会覆盖前面的同名规则)
"eslint:recommended",
"plugin:vue/vue3-recommended",
"plugin:@typescript-eslint/recommended",
"prettier", // 关闭与 Prettier 冲突的格式类规则
],
rules: { // 项目级规则覆盖
"no-unused-vars": "warn",
"vue/multi-word-component-names": "off",
},
ignorePatterns: ["dist/", "node_modules/"],
};| 配置项 | 作用 |
|---|---|
env | 声明运行环境,提供对应全局变量 |
parser | 决定用什么把源码解析成 AST(如 TS、JSX 解析器) |
parserOptions | 解析器的语法选项(ECMAScript 版本、模块类型) |
plugins | 加载第三方规则集,供 rules/extends 使用 |
extends | 继承预设配置,如 eslint:recommended |
rules | 直接配置规则的开启状态与级别 |
ignorePatterns | 忽略某些目录/文件的检查 |
四、规则与规则级别
4.1 规则级别
| 级别 | 值 | 行为 | 退出码 |
|---|---|---|---|
| off | "off" 或 0 | 关闭该规则 | — |
| warn | "warn" 或 1 | 警告,不导致失败 | 0 |
| error | "error" 或 2 | 错误,导致检查失败 | 1 |
4.2 常用规则
rules: {
"no-unused-vars": ["warn", { argsIgnorePattern: "^_" }], // 未使用变量
"eqeqeq": ["error", "always"], // 强制 === / !==
"no-console": ["warn", { allow: ["warn", "error"] }], // 禁止 console.log
"no-undef": "error", // 未定义变量
"prefer-const": "warn", // 优先 const
"no-var": "error", // 禁止 var
"no-empty": "error", // 禁止空代码块
"no-debugger": "warn", // 禁止 debugger
"curly": "error", // 强制块语句加大括号
}// eqeqeq 规则检查的典型问题
if (x == 1) { } // 报错:应使用 ===
if (x === 1) { } // 通过五、extends 配置体系
extends 让团队无需从零写规则,站在社区肩膀上:
| 预设 | 内容 |
|---|---|
eslint:recommended | ESLint 官方推荐规则(常用 100 多条) |
eslint:all | 全部规则(过于严格,慎用) |
eslint-config-airbnb | Airbnb 风格,社区最流行,规则最全面(需配 React 相关插件) |
eslint-config-standard | Standard 风格(无分号等) |
plugin:vue/vue3-recommended | Vue 官方推荐规则集 |
plugin:@typescript-eslint/recommended | TypeScript 推荐规则集 |
prettier | eslint-config-prettier,关闭所有格式类规则 |
npm install -D eslint-config-airbnb eslint-plugin-import eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-jsx-a11yextends: [
"airbnb", // Airbnb 全套风格
"plugin:react/recommended",
"prettier", // 放最后,关闭冲突的格式规则
],自定义规则简介:写一个插件本质上就是导出若干"规则函数",每个函数返回一个对象,用 create 方法返回 AST 节点的访问器:
// 自定义规则示例:禁止 debugger 语句
module.exports = {
meta: { type: "suggestion", docs: { description: "禁止 debugger" } },
create(context) {
return {
DebuggerStatement(node) { // 命中 DebuggerStatement 节点
context.report({ node, message: "不要使用 debugger 语句" });
},
};
},
};六、Prettier:格式化工具
Prettier 只做一件事:按统一规则重新排版代码,消除团队格式争论。
npm install -D prettier
npx prettier --write src/ # 格式化整个目录6.1 配置 .prettierrc
{
"semi": true,
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2,
"trailingComma": "es5",
"arrowParens": "always",
"endOfLine": "lf"
}| 选项 | 默认值 | 说明 |
|---|---|---|
printWidth | 80 | 单行最大宽度,超长自动换行 |
tabWidth | 2 | 缩进宽度 |
semi | true | 行尾是否加分号 |
singleQuote | false | 是否使用单引号 |
trailingComma | "all" | 尾逗号("es5" 表示仅对象/数组) |
arrowParens | "always" | 箭头函数参数是否加括号 |
endOfLine | "lf" | 换行符统一(Windows 项目常设为 lf 配合 git) |
格式化前:const obj={a:1,b:2}
格式化后:const obj = { a: 1, b: 2 };七、ESLint 与 Prettier 冲突解决
ESLint 里也有一批"格式类"规则(如缩进、引号、分号),与 Prettier 职责重叠、标准不一,会互相打架。解决方案是分工:
| 工具 | 职责 |
|---|---|
| ESLint | 只做"质量检查"(未使用变量、===、bug 模式) |
| Prettier | 只做"格式排版"(缩进、引号、换行) |
npm install -D eslint-config-prettier// .eslintrc.js
module.exports = {
extends: [
"eslint:recommended",
"prettier", // 必须放在最后:关闭所有与 Prettier 冲突的格式规则
],
};旧方案里还有个 eslint-plugin-prettier(把 Prettier 当 ESLint 规则跑),官方已不推荐与 eslint-config-prettier 同时使用,现代项目用"ESLint 管质量 + Prettier 管格式 + 分别执行"即可。
八、编辑器集成
VSCode 中安装 ESLint 与 Prettier 扩展后,配置保存自动修复:
// .vscode/settings.json
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"eslint.validate": ["javascript", "typescript", "vue"]
}// package.json 中配套脚本
{
"scripts": {
"lint": "eslint src --ext .js,.vue",
"lint:fix": "eslint src --ext .js,.vue --fix",
"format": "prettier --write src"
}
}保存文件时:Prettier 自动格式化 + ESLint 自动修复可修复问题,红线即为未自动修复的错误。
九、husky + lint-staged 提交前检查
单靠编辑器管不住所有人,在 git 提交前强制检查是最后一道防线:
npm install -D husky lint-staged
npx husky init # 生成 .husky/ 目录// package.json
{
"scripts": {
"lint-staged": "lint-staged"
},
"lint-staged": {
"*.{js,jsx,ts,tsx,vue}": ["eslint --fix", "prettier --write"],
"*.{json,css,scss,md}": ["prettier --write"]
}
}# .husky/pre-commit 文件内容
npx lint-stagedlint-staged 的妙处:只检查暂存区里被修改的文件,而不是全量代码,提交瞬间完成;配合 --fix 自动修复后文件会被重新加入暂存。
git commit 触发流程
→ husky 执行 pre-commit 钩子
→ lint-staged 挑出暂存文件
→ 对每个文件跑 eslint --fix / prettier
→ 有问题则提交失败,全部通过才提交十、工作流总结
| 环节 | 工具 | 时机 |
|---|---|---|
| 代码质量 | ESLint | 编辑器实时 + 提交前 |
| 代码格式 | Prettier | 编辑器保存 + 提交前 |
| 提交拦截 | husky + lint-staged | git commit 前 |
| 团队统一 | extends 预设 + 共享配置文件 | 项目初始化 |
配置文件的组合拳可以概括为:extends 继承社区最佳实践 → rules 微调项目细节 → prettier 关闭冲突格式规则 → husky 保证落地执行。一套配置,全队受益。