第7章 7.2 工程化:ESLint + Prettier + Husky
上章回顾:上一章我们折腾了 Vite 的配置文件,学会了怎么自定义构建行为、优化开发体验。现在你的项目跑得挺欢了,但有个新问题冒出来了——
人多了一起写代码,问题就多了:
- 张三用 Tab 缩进,李四用空格,项目打开一团糟
- 王五写了段 let a = 1;,赵六写了 const a: number = 1,谁对谁错?
- 每次 commit 之前,手动跑检查?太累了,忘了吧……
学完这章你能解决:代码规范混乱、每次提交前手动检查的繁琐、团队协作时代码风格不统一的问题。
1. 🎯 开场:想象一个没有"交通规则"的工地
想象你去一个建筑工地:
- 有人用锤子敲螺丝,有人用螺丝刀钉钉子
- 有人穿拖鞋进场,有人不戴安全帽
- 没有统一指挥,材料乱堆乱放
这样的工地,迟早要出事故。代码项目也一样——没有统一的规范,多人协作就是灾难。
ESLint、Prettier、Husky 就是代码工地的"交通规则"和"安全帽\n\n
\n\n
\n\n":
- ESLint:检查代码有没有"违章"(语法错误、坏味道)
- Prettier:统一代码"长相"(缩进、换行、引号风格)
- Husky:每次"进场施工"前(git commit),强制检查一遍
2. 🧱 基础:三个工具各管什么?
2.1 ESLint——代码警察
是什么:一个代码检查工具,专门抓"坏代码"。
生活类比:就像驾校的考官,拿着打分表看你动作规不规范。压线了吗?闯红灯了吗?
为什么要用:
- 提前发现潜在的 bug(比如写了 == 而不是 ===)
- 强制团队遵守同一套代码规范
- 减少 code review 时因为格式问题吵架
怎么用(以 Vue3 + TypeScript 项目为例):
# 1. 先安装(如果还没装的话)
npm install eslint eslint-plugin-vue @typescript-eslint/parser @typescript-eslint/eslint-plugin --save-dev
# 2. 创建配置文件 .eslintrc.cjs
// .eslintrc.cjs
module.exports = {
root: true,
parser: 'vue-eslint-parser', // 解析 Vue 文件
parserOptions: {
parser: '@typescript-eslint/parser', // 解析 TypeScript
ecmaVersion: 2022,
sourceType: 'module',
},
extends: [
'plugin:vue/vue3-recommended', // Vue3 官方规范
'plugin:@typescript-eslint/recommended', // TypeScript 推荐规范
],
rules: {
// 自定义规则:禁止 console.log
'no-console': 'warn',
// 自定义规则:强制使用单引号
'quotes': ['warn', 'single'],
// 关闭某些过于严格的规则
'@typescript-eslint/no-explicit-any': 'off',
},
}
解释:这个配置文件告诉 ESLint 要检查什么、用什么规则。张三写 console.log('hello'),ESLint 会警告:"嘿,禁止用 console.log!"
2.2 Prettier——代码美容师
是什么:一个代码格式化工具,把你的代码"美容"成统一的样子。
生活类比:就像整形医院,你给它一张照片,它还你一张完美自拍。甭管你原来长什么样,整完都一个样。
为什么要用:
- ESLint 管"逻辑规范",Prettier 管"视觉规范"
- 两人分工,职责清晰
- 配置简单,效果立竿见影
怎么用:
# 1. 安装
npm install prettier --save-dev
# 2. 创建配置文件 .prettierrc
// .prettierrc
{
"semi": true, // 句末加分号
"singleQuote": true, // 使用单引号
"tabWidth": 2, // Tab 宽度 2 空格
"trailingComma": "all", // 尽可能尾随逗号
"printWidth": 80 // 一行最多 80 字符
}
// .prettierrc.js
module.exports = {
semi: true,
singleQuote: true,
tabWidth: 2,
trailingComma: 'all',
printWidth: 80,
}
解释:配置完这个,你写的 const a=1 会被 Prettier 自动变成 const a = 1。这就是"美容"——统一、安全、好看。
2.3 Husky——Git 门口的保安
是什么:在 Git 操作(如 commit、push)之前,自动运行你指定脚本的工具。
生活类比:就像地铁安检,你进站之前必须过一遍安检机。危险品?别想进去!
为什么要用:
- 强制在 commit 之前跑 ESLint + Prettier
- 防止"带病代码"进入代码库
- 自动化流程,不用依赖人工记忆
怎么用:
# 1. 安装 Husky(需要先初始化 git 仓库)
npm install husky --save-dev
# 2. 初始化 Husky
npx husky install
# 3. 添加一个 pre-commit 钩子(在 commit 之前执行)
npx husky add .husky/pre-commit "npx eslint src/ --fix && npx prettier src/ --write"
# 4. 以后每次 git commit 都会自动跑 ESLint + Prettier
解释:加完这个钩子,你每次 git commit,Git 都会先跑一遍检查。如果 ESLint 发现问题,commit 会被拦截,代码进不去。
2.4 三者关系:一条流水线
你写代码
git commit
Husky 拦截("等一下,让我先检查")
ESLint 检查("这段代码规范吗?")
Prettier 美容("让我把你整漂亮")
检查通过 → 代码正式提交 ✅
检查失败 → commit 被拒 ❌
3. 🔥 实战:3 个递进小项目
项目 1:给现有 Vue 项目加上 ESLint 检查(5 分钟)
目标:体验 ESLint 怎么抓问题
步骤:
# 在你的 Vue 项目里运行检查
npx eslint src/ --ext .vue,.ts,.js
假设你的 src/utils/format.ts 有这样一段代码:
// src/utils/format.ts
export function formatDate(date: any) {
// 注意:这里用了 any 类型,ESLint 会警告
return date.toLocaleDateString('zh-CN')
}
ESLint 输出:
/src/utils/format.ts
5:9 warning Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
解释:ESLint 发现你用了 any 类型,警告你换成具体类型。这就是"代码警察"在干活。
项目 2:配置 Prettier + ESLint 联动(15 分钟)
目标:让两个工具配合工作,格式化后再检查
步骤 1:安装冲突解决插件
npm install eslint-config-prettier --save-dev
步骤 2:更新 .eslintrc.cjs,在 extends 里加上 Prettier
// .eslintrc.cjs
module.exports = {
root: true,
parser: 'vue-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser',
ecmaVersion: 2022,
sourceType: 'module',
},
extends: [
'plugin:vue/vue3-recommended',
'plugin:@typescript-eslint/recommended',
'prettier', // ← 加这一行,关掉和 Prettier 冲突的 ESLint 规则
],
rules: {
'no-console': 'warn',
'quotes': ['warn', 'single'],
'@typescript-eslint/no-explicit-any': 'off',
},
}
步骤 3:在 package.json 里加一条脚本
{
"scripts": {
"lint": "eslint src/ --ext .vue,.ts,.js",
"format": "prettier src/ --write",
"lint:fix": "eslint src/ --ext .vue,.ts,.js --fix && prettier src/ --write"
}
}
运行:
# 格式化所有代码
npm run format
# 检查代码问题
npm run lint
# 一次性完成格式化和检查
npm run lint:fix
解释:eslint --fix 会自动修复能修复的问题(比如引号、缩进),然后 Prettier 统一美化一遍。
项目 3:完整的 Git Hooks 自动化流程(15 分钟)
目标:实现"提交代码 → 自动检查 → 自动格式化 → 成功提交"一条龙
完整配置步骤:
# 1. 初始化 Git 仓库(如果还没有)
git init
# 2. 安装所有需要的依赖
npm install -D eslint prettier eslint-plugin-vue @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-config-prettier husky lint-staged
# 3. 初始化 Husky
npx husky install
# 4. 创建 pre-commit 钩子
npx husky add .husky/pre-commit "npx lint-staged"
# 5. 在 package.json 里加 lint-staged 配置
{
"lint-staged": {
"*.{vue,ts,js}": [
"eslint --fix",
"prettier --write"
]
}
}
6. 在 .git/hooks/pre-commit 文件里写入:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx lint-staged
使用流程:
# 你修改了一些代码
echo "console.log('hello')" > src/test.ts
# 添加到暂存区
git add src/test.ts
# 提交(这时候 Husky 会自动拦截并检查)
git commit -m "feat: add test file"
# 输出类似:
# ✔ Linting 1 file(s)
# ✔ Formatting 1 file(s)
# [main abc1234] feat: add test file
解释:lint-staged 只检查你这次提交改的文件,不检查整个项目,速度快。Husky 保证每次提交前都必须过这一关。
4. 💪 进阶:常见坑 + 调试技巧
坑 1:ESLint 和 Prettier 规则冲突
❌ 错误示例:两个工具各自为政,ESLint 要求双引号,Prettier 要求单引号
// .eslintrc.cjs(没加 prettier 配置)
rules: {
'quotes': ['error', 'single'], // ESLint 要单引号
}
// .prettierrc
singleQuote: false // Prettier 要双引号
结果:两个工具打起来,代码被改来改去。
✅ 正确做法:在 ESLint 继承 Prettier 配置
// .eslintrc.cjs
extends: [
'plugin:vue/vue3-recommended',
'plugin:@typescript-eslint/recommended',
'prettier', // ← 这行要加在最后
],
坑 2:Husky 钩子没生效
❌ 错误:直接编辑 .husky/pre-commit,但没有给文件执行权限
# 直接写文件,但没有执行权限
echo "npx eslint src/ --fix" > .husky/pre-commit
git commit # 不生效!
✅ 正确做法:用 husky add 命令添加钩子
# 自动创建文件并设置好权限
npx husky add .husky/pre-commit "npx eslint src/ --fix"
chmod +x .husky/pre-commit # 保险起见再加个权限
坑 3:commit 的时候 ESLint 报错,但不知道是哪行
❌ 错误:直接看报错信息,找不到具体位置
src/utils/api.ts
某些错误
✅ 正确做法:加 --max-warnings=0 让警告也失败
npx eslint src/ --max-warnings=0
或者在 CI 环境下运行完整检查:
npm run lint
if [ $? -ne 0 ]; then
echo "ESLint 检查失败,请修复后再提交"
exit 1
fi
坑 4:大型项目 lint 速度太慢
❌ 错误:每次 commit 检查整个项目,等半天
✅ 正确做法:用 lint-staged 只检查改动的文件
// package.json
{
"lint-staged": {
"*.{vue,ts,js}": [
"eslint --fix",
"prettier --write"
]
}
}
坑 5:Windows 系统 Husky 不工作
❌ 错误:在 Windows 上 .husky/_/husky.sh 找不到
✅ 正确做法:Windows 用户用管理员权限的 PowerShell:
# 以管理员身份运行 PowerShell
Set-ExecutionPolicy -Scope LocalMachine -ExecutionPolicy RemoteSigned
npx husky install
调试技巧:VSCode 实时检查
安装 VSCode 插件 ESLint 和 Prettier,保存文件时自动检查和格式化:
// .vscode/settings.json
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
效果:你敲代码的时候,VSCode 实时显示红色的错误波浪线,一保存就自动修复。
5. ✏️ 练习题
练习 1(1 分钟):认识 ESLint 输出
- 输入:你运行
npx eslint src/App.vue - 输出:显示
1 error, 2 warnings - 提示:
--max-warnings=0可以把警告当错误处理
练习 2(2 分钟):给规则加个开关
- 输入:在
.eslintrc.cjs里把no-console从warn改成error - 预期输出:再运行
npm run lint,console.log 会导致失败 - 提示:规则值可以是
'off'、'warn'、'error'
练习 3(3 分钟):配置 Prettier 尾随逗号
- 输入:把
.prettierrc改成"trailingComma": "none" - 预期输出:格式化后
const obj = { a: 1 }(对象后面没逗号) - 提示:
"all"会尽可能加尾随逗号
练习 4(5 分钟):把两个工具串起来
- 输入:在
package.json里写一个dev:fix脚本,先跑 ESLint 再跑 Prettier - 预期输出:
npm run dev:fix能一次性完成检查和格式化 - 提示:脚本可以用
&&连接两个命令
练习 5(5 分钟):分析报错截图(模拟)
- 输入:Husky 拦截了 commit,报错
Cannot find module 'eslint' - 预期输出:说出原因并修复
- 提示:检查依赖有没有装,或者用
npx代替直接调用
作业:做一个「代码规范自动化工具」
需求描述:为一个小型 Vue3 项目配置完整的代码规范流程
功能点:
1. 配置 ESLint + TypeScript + Vue3 规则
2. 配置 Prettier 格式化规则
3. 配置 Husky + lint-staged 自动化流程
4. 写一个使用说明 CONTRIBUTING.md,告诉队友怎么用
加分项:
1. 配置一个 commitlint 规范提交信息格式(如 feat:、fix:)
2. 配置 GitHub Actions CI,在 PR 时自动跑检查
验收标准:
- 能跑 git commit 且自动触发检查
- ESLint 和 Prettier 冲突时报错
- 提交信息不符合规范时 commit 被拒
6. 📚 总结 + 资源
本文学了 3 件事:
1. ESLint 是代码警察,管"逻辑规范"
2. Prettier 是美容师,管"视觉规范"
3. Husky 是门口的保安,保证"进场前必须过安检"
延伸资源:
- ESLint 官方文档(英文,但例子清晰)
- Prettier 官方文档(配置项最全)
- Husky GitHub 仓库(更新频繁,Windows 兼容性说明很有用)
互动钩子:你在团队项目里被 ESLint 拦截过吗?当时是因为什么规则?评论区聊聊,老粉优先回复!
下章预告:下一章我们要解决一个更复杂的问题——当项目越来越大,里面有好多好多子项目的时候,怎么管理?pnpm workspace 就是答案……

评论(0)