VS Code 格式化配置优先级与作用机制(包含ESLint)
另外一篇: VS Code 格式化配置优先级与作用机制(不含ESlint)
📋 概述
加入 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与其他格式化工具的协作,可以实现既保证代码质量又统一代码风格的目标!