ESLint + Prettier:代码风格统一神器,让团队不再为分号吵架
手把手教你配置 ESLint 和 Prettier,从此告别代码风格争论,让工具替你做决定。
代码风格之战:一场没有赢家的争论
"用 Tab 还是空格?"
"分号要不要加?"
"花括号换行还是不换行?"
如果你在团队里工作过,一定经历过这样的讨论。而且你会发现,这些讨论往往比技术架构的讨论还激烈——因为每个人都有自己的"舒适区"。
我曾经见过两个同事为了"对象最后一个属性要不要加逗号"这个问题,在群里吵了整整一下午。最后的结论是什么呢?没有结论,各写各的。
结果就是:代码库里风格混乱,有的文件用 Tab,有的用空格;有的加分号,有的不加。每次 Code Review 的时候,50% 的讨论都在纠结格式问题,真正的逻辑问题反而被忽略了。
今天,我们要用 ESLint + Prettier 彻底终结这场战争。
先搞清楚:ESLint 和 Prettier 各管啥?
很多人把这两个工具搞混,觉得它们是干同一件事的。其实不然:
ESLint:代码质量警察
ESLint 主要关注的是代码质量和潜在错误:
// ESLint 会警告你这些问题
// 1. 使用了未声明的变量
console.log(userName); // 'userName' is not defined
// 2. 声明了但没使用的变量
const unused = 'hello'; // 'unused' is defined but never used
// 3. 可能的逻辑错误
if (x = 1) { // Expected '===' and instead saw '='
console.log('oops');
}
// 4. 不推荐的写法
with (obj) { // Unexpected use of 'with' statement
console.log(name);
}
Prettier:代码格式美容师
Prettier 只关注代码格式,它不管你的代码逻辑对不对,只管让代码"好看":
// Prettier 处理前
const user={name:'小明',age:25,skills:['JavaScript','TypeScript','Vue','React']}
// Prettier 处理后
const user = {
name: "小明",
age: 25,
skills: ["JavaScript", "TypeScript", "Vue", "React"],
};
一句话总结
- ESLint:检查代码写得对不对
- Prettier:检查代码写得美不美
这两个工具配合使用,才是完整的代码规范解决方案。
从零开始配置:手把手教程
第一步:安装依赖
# 创建一个新项目(如果你已有项目,跳过这步)
mkdir my-project && cd my-project
npm init -y
# 安装 ESLint
npm install eslint --save-dev
# 安装 Prettier
npm install prettier --save-dev
# 安装 ESLint 和 Prettier 的配合插件(重要!)
npm install eslint-config-prettier eslint-plugin-prettier --save-dev
这里要解释一下最后安装的两个包:
eslint-config-prettier:关闭 ESLint 中与 Prettier 冲突的规则eslint-plugin-prettier:让 ESLint 能够运行 Prettier 检查
第二步:配置 ESLint
创建 .eslintrc.js 文件:
module.exports = {
env: {
browser: true,
es2021: true,
node: true,
},
extends: [
'eslint:recommended',
'plugin:prettier/recommended', // 这行放在最后!
],
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
rules: {
// 在这里添加你的自定义规则
'no-console': 'warn',
'no-unused-vars': 'warn',
'prefer-const': 'error',
},
};
重点:plugin:prettier/recommended 一定要放在 extends 数组的最后,因为它会覆盖前面的格式相关规则。
第三步:配置 Prettier
创建 .prettierrc 文件:
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"printWidth": 80,
"bracketSpacing": true,
"arrowParens": "avoid"
}
让我来解释每个配置的含义:
| 配置 | 含义 | 示例 |
|---|---|---|
semi: true | 语句末尾加分号 | const a = 1; |
singleQuote: true | 使用单引号 | 'hello' |
tabWidth: 2 | 缩进用 2 个空格 | ··if (true) |
trailingComma: "es5" | 对象/数组末尾加逗号 | { a: 1, b: 2, } |
printWidth: 80 | 每行最多 80 字符 | 自动换行 |
bracketSpacing: true | 对象括号内加空格 | { a: 1 } |
arrowParens: "avoid" | 箭头函数单参数不加括号 | x => x * 2 |
第四步:添加忽略文件
创建 .eslintignore:
node_modules
dist
build
*.min.js
创建 .prettierignore:
node_modules
dist
build
pnpm-lock.yaml
package-lock.json
第五步:添加 npm scripts
在 package.json 中添加:
{
"scripts": {
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",
"lint:fix": "eslint . --ext .js,.jsx,.ts,.tsx --fix",
"format": "prettier --write .",
"format:check": "prettier --check ."
}
}
进阶配置:TypeScript 项目
如果你的项目使用 TypeScript,需要额外安装一些依赖:
npm install @typescript-eslint/parser @typescript-eslint/eslint-plugin --save-dev
然后修改 .eslintrc.js:
module.exports = {
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
],
rules: {
// TypeScript 相关规则
'@typescript-eslint/no-unused-vars': 'warn',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-explicit-any': 'warn',
},
};
进阶配置:Vue 项目
Vue 项目需要额外的解析器:
npm install eslint-plugin-vue --save-dev
.eslintrc.js 配置:
module.exports = {
extends: [
'eslint:recommended',
'plugin:vue/vue3-recommended', // Vue 3 项目
// 'plugin:vue/recommended', // Vue 2 项目
'plugin:prettier/recommended',
],
rules: {
'vue/multi-word-component-names': 'off',
'vue/no-v-html': 'warn',
},
};
编辑器集成:保存时自动格式化
配置文件写好了,但每次都要手动运行命令太麻烦。让我们配置编辑器自动格式化。
VS Code 配置
安装插件:
- ESLint
- Prettier - Code formatter
创建 .vscode/settings.json:
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
现在,每次保存文件时:
- Prettier 会自动格式化代码
- ESLint 会自动修复可以修复的问题
爽翻了!
Git Hooks:提交前自动检查
编辑器配置好了,但万一有人不用 VS Code 呢?万一有人忘记保存就提交了呢?
我们需要一道最后的防线:Git Hooks。
安装 Husky 和 lint-staged
npm install husky lint-staged --save-dev
# 初始化 Husky
npx husky install
# 添加 pre-commit hook
npx husky add .husky/pre-commit "npx lint-staged"
配置 lint-staged
在 package.json 中添加:
{
"lint-staged": {
"*.{js,jsx,ts,tsx,vue}": [
"eslint --fix",
"prettier --write"
],
"*.{json,md,css,scss}": [
"prettier --write"
]
}
}
现在,每次 git commit 之前,都会自动对暂存的文件进行:
- ESLint 检查和修复
- Prettier 格式化
如果有错误无法自动修复,提交会被阻止。再也不用担心格式问题流入代码库了!
常见问题排查
问题 1:ESLint 和 Prettier 规则冲突
症状:保存时代码反复跳动,或者 ESLint 报错 Prettier 刚改的格式。
解决:确保 eslint-config-prettier 在 extends 数组的最后位置。
extends: [
'eslint:recommended',
'plugin:prettier/recommended', // 必须在最后
],
问题 2:.vue 文件格式化不生效
症状:JS/TS 文件正常,但 Vue 文件不格式化。
解决:在 .vscode/settings.json 中明确指定:
{
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
问题 3:某个规则太烦人想关闭
症状:某个 ESLint 规则频繁报错,但你觉得没必要。
解决:在 .eslintrc.js 的 rules 中关闭:
rules: {
'no-console': 'off', // 关闭规则
'no-unused-vars': 'warn', // 改为警告
}
问题 4:想在某个文件临时禁用规则
解决:使用注释禁用:
/* eslint-disable no-console */
console.log('这里不会报警告');
/* eslint-enable no-console */
// 或者只禁用一行
console.log('just this line'); // eslint-disable-line no-console
我的推荐配置
分享一下我团队目前使用的配置,可以直接拿去用:
.prettierrc
{
"semi": false,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "all",
"printWidth": 100,
"bracketSpacing": true,
"arrowParens": "avoid",
"endOfLine": "lf",
"vueIndentScriptAndStyle": true
}
是的,我们选择了不加分号。理由是:
- 现代 JavaScript 的自动分号插入(ASI)已经很完善
- 少打一个字符,代码更简洁
- TypeScript/Prettier 会帮你处理边界情况
.eslintrc.js
module.exports = {
root: true,
env: {
browser: true,
es2021: true,
node: true,
},
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:vue/vue3-recommended',
'plugin:prettier/recommended',
],
parser: 'vue-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser',
ecmaVersion: 'latest',
sourceType: 'module',
},
rules: {
// 允许 console,但生产环境打包时应该移除
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
// TypeScript
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
'@typescript-eslint/no-explicit-any': 'warn',
// Vue
'vue/multi-word-component-names': 'off',
'vue/no-v-html': 'off',
},
}
写在最后
配置 ESLint + Prettier 可能会花你一两个小时,但它带来的收益是巨大的:
- 团队不再为代码风格争论——工具说了算
- Code Review 更高效——专注于逻辑,而非格式
- 代码库保持一致——无论谁写的代码,看起来都一样
- 减少低级错误——ESLint 帮你提前发现问题
记住一句话:好的工具应该让人感觉不到它的存在。配置完成后,你只需要专注于写代码,格式化的事情就交给工具吧。
下一篇,我们来聊聊 async/await 的错误处理——这可是面试必考题哦。