前期规范主要针对Vue2的历史项目,近期对Vue3项目的规则做了统一梳理,具体如…
系列文章:
前置背景
1.适用范围
主要针对:Vue3技术栈及相关生态的代码规则配置,其中 Node 版本大于18,且ESLint 版本大于8。
package.json
配置如下:
{
"engines": {
"node": ">=18"
},
"peerDependencies": {
"eslint": "^8"
}
}
2.Vue3项目创建
使用Vite
初始化Vue3
项目,更多参考 搭建Vite项目
# npm 7+, 需要额外加 --:
$ npm create vite@latest <project-name> -- --template vue-ts
一、配置ESLint
、TS
和 Prettier
1. 依赖安装
这里介绍两种安装依赖的方式,第一种是参考给出的package.json进行配置安装,第二种是按照命令,依次安装配置。
1.1 按照package.json
安装配置
参考以下package.json
,在项目根目录执行:
$ npm i
package.json
:
{
"name": "vue3-ts-eslint-h5",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc -b && vite build",
"lint": "eslint --ext .js,.vue,.ts src",
"lint:fix": "eslint --ext .js,.vue,.ts src --fix"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"eslint": "^8"
},
"dependencies": {
"vue": "^3.4.29",
"vite": "^5.3.1",
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^7.14.1",
"@typescript-eslint/parser": "^7.14.1",
"@vitejs/plugin-vue": "^5.0.5", // 无关 - 可注释
"@vue/eslint-config-standard": "^8.0.1",
"@vue/eslint-config-typescript": "^13.0.0",
"eslint": "8.56.0",
"eslint-config-airbnb-base": "15.0.0", // js 相关
"eslint-config-prettier": "9.1.0",
"eslint-plugin-prettier": "5.1.3",
"eslint-plugin-vue": "9.26.0",
"eslint-plugin-import": "2.29.1", // eslint-config-airbnb-base 前置插件
"prettier": "^3.3.2",
"typescript": "^5.2.2",
"vue-tsc": "^2.0.21", // 无关 - 可注释
"lint-staged": "^9.1.0", // 无关 - git commit 检测eslint机制
},
"lint-staged": {
"*.{js,ts,vue}": [
"eslint --fix",
"git add"
],
"src/**/*.{vue,css,sass,scss}": [
"stylelint --fix",
"git add"
]
},
// 在.prettier配置,可代替此处配置
"prettier": {
// ...
}
}
1.2 手动配置安装
手动添加ESLint
和TypeScript
支持:
npm install --save-dev eslint eslint-plugin-vue typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin
npx install-peerdeps --dev eslint-config-airbnb-base
npm install --save-dev eslint-plugin-vue eslint-plugin-import
手动添加Prettier
支持:
npm install --save-dev prettier eslint-config-prettier eslint-plugin-prettier
2. 配置ESLint
、TS
和 Prettier
2.1 tsconfig.json
文件
确保项目根目录有tsconfig.json
文件。以下是基本的TypeScript
配置示例:
{
"extends":"./other_tsconfig/tsconfig.json",
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
},
"lib": ["esnext", "dom"],
// ---------------- 新增(待定)---------------
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"exclude": ["node_modules"]
}
2.2 .prettierrc
文件
在项目根目录创建.prettierrc
文件:
{
"singleQuote": true,
"tabWidth": 2,
"semi": false,
"eslintIntegration": true,
"printWidth": 120,
"endOfLine": "auto",
"arrowParens": "always",
"trailingComma": "none",
}
依赖.eslintrc.js
中扩展Prettier
配置:
// ...,
extends: [
// ...
'prettier',
],
2.3 .eslintrc.js
文件
在项目根目录下创建.eslintrc.js
文件,并配置ESLint
规则。以下是一个基本的配置示例:
module.exports = {
root: true,
env: {
node: true,
browser: true,
es6: true,
},
globals: {},
plugins: ['@typescript-eslint', 'vue'],
extends: [
'airbnb-base', // js
'eslint:recommended',
'@vue/typescript/recommended', // 启用 Vue + TypeScript 推荐的 ESLint 配置
'plugin:vue/vue3-recommended', // 启用 Vue 3 推荐的 ESLint 配置
'plugin:prettier/recommended', // 确保 Prettier 格式化的代码不被 ESLint 覆盖
'prettier',
],
ignorePatterns: ['.eslintrc.js'],
parser: 'vue-eslint-parser', // 使用 Vue 专用的解析器以便解析 .vue 文件
parserOptions: {
parser: '@typescript-eslint/parser', // 使用 TypeScript 解析器解析 .ts 和 .tsx 文件
extraFileExtensions: ['.vue'],
project: './tsconfig.json'
ecmaVersion: 2020, // 支持 ECMAScript 2020 的语法块
sourceType: 'module', // 代码使用 ES 模块
// ecmaFeatures: { // 允许在代码中使用 JSX
// jsx: true,
// },
},
rules: {
// ------------------ 公共 ------------------
'prettier/prettier': ['warn'],
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'@typescript-eslint/no-explicit-any': 'off',
'import/no-extraneous-dependencies': 'off',
// ------------------ 新增 js ------------------
// non stylistic rules which are conflict with airbnb-base
'no-empty': ['warn', { allowEmptyCatch: true }],
'no-unused-vars': ['warn', { args: 'none' }],
'arrow-body-style': ['off'],
'import/first': 'off', // 防止出现首行报红问题
'no-use-before-define': 'off',
'complexity': ['warn', { max: 10 }], // 配置 eslint 的 complexity
// ------------------ 新增 ts ------------------
'@typescript-eslint/unbound-method': ['off'], // 在 vue 项目中 不用担心 this 丢失问题,包括 .vue, mixins
'@typescript-eslint/no-use-before-define': ['error'], // 你不能在定义变量、函数、类等之前使用它们
'@typescript-eslint/no-unused-vars': 'off', // 关闭此规则,避免对未使用的变量发出警告
// '@typescript-eslint/no-explicit-any': 'error', // 不允许使用any类型
复杂度,约束每个函数的最大if分支数
// ------------------ 新增 vue3 ------------------
'vue/multi-word-component-names': 'off', // 避免与 HTML 原生元素名称冲突
'vue/script-setup-uses-vars': 'error', // 确保 script setup 中的变量在 template 中被正确识别
},
overrides: [
{
files: ['*.vue'],
rules: {
'vue/require-direct-export': ['off'],
},
},
{
files: ['**/__tests__/*.{j,t}s?(x)', '**/tests/unit/**/*.spec.{j,t}s?(x)']
}
]
};
二、常见ESLint规则校验失败类型
常见ESLint规则校验失败类型,主要分为两类: 可自动修复的和需手动修复的
1. 可自动修复的
$ npm run lint # 检测
$ npm run lint:fix # 修复
2. 需手动修复的
主要包括:
- TS类型规范和参数规范
- 包的导入规范
- 变量命名
// camelcase 推荐使用 camelCase 来命名变量和函数
// 示例:将 oa_nextNodeAssignee 重命名为 oaNextNodeAssignee 或其他符合 camelCase 约定的名称
// no-new
// 用了 new 关键字来创建一个对象,但这个对象没有被赋值给任何变量,也没有被用作表达式的一部分。
// 这通常被视为一种不良实践,因为它可能导致不必要的资源分配或难以跟踪的副作用
// complexity - warning 某个函数的中的决策点(如if语句、for循环、while循环、case语句等)
// 复杂程度过高
// 详细错误示例:warning Arrow function has a complexity of 13. Maximum allowed is 10 complexity
// eslint-disable-next-line complexity
const myComplexFunction = () => {
// ... function body
};
// no-underscore-dangle
// 禁止在变量名中使用前导或尾随下划线(除了 _、__proto__、constructor、Object.prototype 的属性或方法外)
// no-useless-escape 正则表达式中不必要的转义字符的错误
// prefer-regex-literals 规则推荐使用正则表达式字面量来替代 RegExp 构造函数
// 如:你的代码是 new RegExp('\\d+'),可以替换为 /\d+/
// prefer-promise-reject-errors 将 Promise 的拒绝原因改为 Error 对象
// no-async-promise-executor 错误发生在尝试将 async 关键字用于 Promise 的执行函数(executor function)中时
// bad
const validateTaxCode = (value: any) =>
new Promise(async (resolve) => {
const res = await checkLastSubject({
subjectCode: value
})
resolve(res)
})
}
// good
const validateTaxCode = (value: any) =>
new Promise((resolve) => {
const res = await checkLastSubject({
subjectCode: value
})
resolve(res)
})
}
// 严格等于 eqeqeq
// ESLint 建议使用 === 而不是 ==,因为 === 会比较值和类型,而 == 会在比较前尝试进行类型转换,这可能会导致意外的结果
// 重复导入 import/no-duplicates
// bad
import { defineRuntimeHooks } from '@zto/zmi'
import { getEnv } from '@zto/zmi'
// good
import { defineRuntimeHooks, getEnv } from '@zto/zmi'
// TS类型错误
// @typescript-eslint/no-unused-vars // 定义了一个名为 xxx 的变量或导入,但它在代码中从未被使用过
// @typescript-eslint/no-unsafe-argument // 没有为变量或属性提供明确的类型,或者从某些函数/方法中获取了未明确指定类型的值时
// @typescript-eslint/no-use-before-define // 表明你在使用 xxx 方法前没有先定义它
// @typescript-eslint/no-unsafe-enum-comparison // 枚举(enum)类型和你的判断条件不匹配
三、常见配置问题
1. 当前版本为Node 16,如何对以上eslint相关包降级处理?
package.json
配置要求如下:
{
"engines": {
"node": ">=16"
},
"peerDependencies": {
"eslint": "^7.2.0 || ^8"
},
}
首先,是ESLint
相关的包,因为要求Node 版本大于18,所以进行降级
{
"@typescript-eslint/eslint-plugin": "7.14.1", // 7.2.0
"@typescript-eslint/parser": "7.14.1", // 7.2.0
"@vue/eslint-config-typescript": "13.0.0" // 12.0.0
}
其次,执行npm run lint
,报错如下:
$ npm run lint
> zmi-test@1.0.3 lint
> eslint --ext .js,.vue,.ts src
=============
WARNING: You are currently running a version of TypeScript which is not officially supported by @typescript-eslint/typescript-estree.
You may find that it works just fine, or you may not.
SUPPORTED TYPESCRIPT VERSIONS: >=4.7.4 <5.5.0
YOUR TYPESCRIPT VERSION: 5.5.2
Please only submit bug reports when using the officially supported version.
=============
在 @typescript-eslint/parser
包的依赖 @typescript-eslint/typescript-estree
, 其前置依赖的typescript
有版本要求,需要降级处理
{
"typescript": "5.5.2" // 降级 4.7.4
}
综上,最终降级后的包版本如下:
{
"@typescript-eslint/eslint-plugin": "7.2.0",
"@typescript-eslint/parser": "7.2.0",
"@vue/eslint-config-typescript": "12.0.0",
"typescript": "4.7.4"
}
参考
最后, 希望大家早日实现:成为编程高手的伟大梦想!
欢迎交流~
本文版权归原作者曜灵所有!未经允许,严禁转载!对非法转载者, 原作者保留采用法律手段追究的权利!
若需转载,请联系微信公众号:连先生有猫病,可获取作者联系方式!