📋 概述
加入 ESLint 后,代码格式化变得更加复杂,因为 ESLint 既负责代码质量检查,也可以处理代码格式化。这会与 Prettier 等格式化工具产生潜在冲突。
🔢 新的优先级顺序(从高到低)
1. .vscode/settings.json (项目级)
├── editor.codeActionsOnSave (ESLint自动修复)
├── editor.defaultFormatter (格式化器选择)
└── eslint.* (ESLint特定配置)
2. .eslintrc.js/.eslintrc.json (项目级)
├── rules (ESLint规则)
├── extends (继承的规则集)
└── plugins (ESLint插件)
3. .editorconfig (项目级)
└── 基础编辑器规则
4. .prettierrc (项目级)
└── Prettier格式化规则
5. 用户设置 settings.json (全局)
└── 全局默认设置
6. 默认设置
⚡ ESLint 在格式化流程中的双重角色
🔍 角色1: 代码质量检查器
// ESLint 检查这些问题:
const unusedVar = 'hello'; // ❌ no-unused-vars
console.log(undefinedVar); // ❌ no-undef
if (x = 5) { /* ... */ } // ❌ no-cond-assign
🎨 角色2: 代码格式化器
// ESLint 也可以修复格式问题:
const name="张三" // ❌ quotes: ['error', 'single']
const name = "张三"; // ✅ 自动修复为: const name = '张三';
function test(){return true} // ❌ space-before-blocks
function test() { return true; } // ✅ 自动修复
📁 配置文件详解(包含ESLint)
1. .eslintrc.js (项目级)
位置: 项目根目录/.eslintrc.js
作用:
- 定义代码质量和格式化规则
- 可以自动修复部分问题
- 与其他格式化工具可能冲突
Vue 2 项目示例:
module.exports = {
env: {
browser: true,
node: true,
es6: true
},
extends: [
'plugin:vue/recommended',
'eslint:recommended',
'prettier', // 关闭与Prettier冲突的规则
'prettier/vue' // Vue特定的Prettier兼容
],
plugins: ['vue', 'prettier'],
rules: {
// 代码质量规则
'no-unused-vars': 'error',
'no-console': 'warn',
// 格式化规则(建议由Prettier处理)
'quotes': ['error', 'single'],
'semi': ['error', 'always'],
'indent': ['error', 2],
// Prettier集成
'prettier/prettier': 'error', // 将Prettier规则作为ESLint错误
// Vue特定规则
'vue/max-attributes-per-line': ['error', {
'singleline': 10,
'multiline': { 'max': 1 }
}]
}
};
2. 更新的 .vscode/settings.json
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit", // ESLint自动修复
"source.organizeImports": "explicit" // 整理导入
},
"[vue]": {
"editor.defaultFormatter": "octref.vetur" // 主格式化器
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"eslint.validate": [
"javascript",
"javascriptreact",
"vue",
"typescript"
],
"eslint.run": "onSave", // ESLint运行时机
"eslint.format.enable": false // 禁用ESLint格式化,避免冲突
}
🔄 完整的工作流程
保存文件时的执行顺序:
具体执行示例:
原始代码:
// 保存前的代码
const name="张三"
let unusedVar = 'test'
console.log(name)
第1步 - ESLint自动修复:
// ESLint修复后
const name = '张三'; // 修复引号和分号
// let unusedVar = 'test' // 删除未使用变量(如果配置了)
console.log(name); // 添加分号
第2步 - Prettier格式化:
// Prettier格式化后
const name = '张三';
console.log(name);
第3步 - EditorConfig应用:
// 确保缩进、换行符等符合.editorconfig
const name = '张三';
console.log(name);
⚔️ ESLint 与 Prettier 冲突解决
常见冲突场景:
| 规则类型 | ESLint规则 | Prettier行为 | 冲突结果 |
|---|---|---|---|
| 引号 | quotes: ['error', 'single'] | "singleQuote": true | ✅ 一致 |
| 分号 | semi: ['error', 'always'] | "semi": true | ✅ 一致 |
| 行长度 | max-len: ['error', 80] | "printWidth": 100 | ❌ 冲突 |
| 缩进 | indent: ['error', 2] | "tabWidth": 4 | ❌ 冲突 |
解决方案1: 使用 eslint-config-prettier
安装依赖:
npm install --save-dev eslint-config-prettier eslint-plugin-prettier
配置 .eslintrc.js:
module.exports = {
extends: [
'eslint:recommended',
'plugin:vue/recommended',
'prettier', // 必须放在最后,禁用冲突规则
'prettier/vue' // Vue相关的Prettier兼容
],
plugins: ['prettier'],
rules: {
'prettier/prettier': 'error', // 将Prettier问题显示为ESLint错误
// 只保留非格式化的规则
'no-unused-vars': 'error',
'no-console': 'warn',
// 删除所有格式化相关的规则,交给Prettier处理
}
};
解决方案2: 分离关注点
ESLint负责: 代码质量
// .eslintrc.js - 只关注代码质量
module.exports = {
rules: {
'no-unused-vars': 'error',
'no-undef': 'error',
'no-console': 'warn',
'vue/no-unused-components': 'error',
// 不包含任何格式化规则
}
};
Prettier负责: 代码格式
// .prettierrc - 只关注格式
{
"semi": true,
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100
}
🛠️ 不同项目的最佳配置
Vue 2 项目配置
.eslintrc.js:
module.exports = {
extends: [
'plugin:vue/recommended',
'eslint:recommended',
'prettier',
'prettier/vue'
],
plugins: ['vue', 'prettier'],
rules: {
'prettier/prettier': 'error',
'no-unused-vars': 'error',
'vue/no-unused-components': 'error'
}
};
.vscode/settings.json:
{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"[vue]": {
"editor.defaultFormatter": "octref.vetur"
},
"vetur.validation.script": false, // 禁用Vetur的ESLint,使用独立ESLint
"eslint.format.enable": false
}
Vue 3 (Nuxt 4) 项目配置
eslint.config.mjs:
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'
export default createConfigForNuxt({
features: {
tooling: true,
stylistic: {
semi: true,
quotes: 'single'
}
}
}).append({
rules: {
'no-console': 'warn',
'@typescript-eslint/no-unused-vars': 'error'
}
})
.vscode/settings.json:
{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"[vue]": {
"editor.defaultFormatter": "Vue.volar"
},
"[typescript]": {
"editor.defaultFormatter": "Vue.volar"
}
}
🎯 执行时机对比
不同阶段的检查和修复:
| 时机 | ESLint | Prettier | EditorConfig |
|---|---|---|---|
| 编辑时 | 🔴 显示错误波浪线 | - | ✅ 应用基础设置 |
| 保存时 | 🔧 自动修复问题 | 🎨 格式化代码 | ✅ 确保一致性 |
| 提交时 | 🚫 阻止提交(Git hooks) | 🎨 预处理格式化 | - |
| CI/CD | ❌ 构建失败 | ✅ 检查格式一致性 | - |
Git Hooks 集成示例:
package.json:
{
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.{js,vue}": [
"prettier --write", // 先格式化
"eslint --fix", // 再修复ESLint问题
"git add" // 添加到提交
]
}
}
🐛 常见问题和解决方案
问题1: 格式化后ESLint仍报错
原因: ESLint格式化规则与Prettier冲突
解决: 安装 eslint-config-prettier 禁用冲突规则
问题2: 保存时格式化两次
原因: ESLint和默认格式化器都在工作
解决: 设置 "eslint.format.enable": false
问题3: Vue文件格式化不一致
原因: 不同部分使用不同格式化器
解决: 统一配置Vetur/Volar的格式化选项
问题4: TypeScript文件ESLint不生效
原因: ESLint没有配置TypeScript支持
解决: 安装 @typescript-eslint/parser 和相关插件
📊 配置文件优先级总结表
| 配置源 | 作用域 | 优先级 | 主要职责 | 典型内容 |
|---|---|---|---|---|
.vscode/settings.json | 项目 | 最高 | 编辑器行为 | 格式化器选择、ESLint设置 |
.eslintrc.js | 项目 | 高 | 代码质量+格式 | 规则定义、插件配置 |
.prettierrc | 项目 | 中 | 代码格式 | 格式化细节规则 |
.editorconfig | 项目 | 中 | 基础编辑器 | 缩进、换行符、编码 |
用户设置 | 全局 | 低 | 默认行为 | 通用编辑器设置 |
🚀 推荐的最佳实践
✅ 推荐做法:
-
明确分工:
- ESLint → 代码质量检查
- Prettier → 代码格式化
- EditorConfig → 基础编辑器设置
-
避免冲突:
- 使用
eslint-config-prettier - 禁用ESLint的格式化功能
- 让Prettier处理所有格式化
- 使用
-
统一配置:
- 在
.vscode/settings.json中明确指定格式化器 - 在
.eslintrc.js中只保留质量相关规则 - 在
.prettierrc中定义统一的格式标准
- 在
❌ 避免的问题:
- 不要在ESLint和Prettier中重复定义相同的格式化规则
- 不要启用多个格式化器同时工作
- 不要忽略
eslint-config-prettier的重要性
通过合理配置ESLint与其他格式化工具的协作,可以实现既保证代码质量又统一代码风格的目标!
730

被折叠的 条评论
为什么被折叠?



