Vue 支持

参考
vue 风格指南
插件规则集 eslint-plugin-vue
使用 Eslint & standard 规范前端代码
各种 lint 预设 pk
为什么推荐使用 prettier
我为什么推荐 Prettier 来统一代码风格
Vue CLI 3.0 文档
ESLint 与 Prettier 配合使用 Typescript 中如何正确使用 ESLint 和 Prettier eslint中文文档

vue cli

基于 webpack 构建的 vue 脚手架工具。

选择代码检测和格式化方案
使用脚手架创建项目的时候,是可以直接选择 eslint 的集成。

选择Linter / Formatter配置:
选项:
  ESLint with error prevention only  // 自带默认规则集
  ESLint + Airbnb config  // Airbnb规则集
  ESLint + Standard config // Standard规则集
  ESLint + Prettier // Prettier则集

默认的规则集太简单,但大家又不喜欢自己来配置繁杂的 rules 规则,所以一般情况下都会选择一些规则集(比较流行的有 airbnb、standard、prettier 等)。

相比之下大家都推荐 Prettier 预设规范,配置更少,用起来更舒服,而且 Prettier 还提供了扩展方便集成到编辑器中进行一键代码格式化

我们来看看比较也能得出结果:

我们分别使用自带默认规则集、Standard 规则集、Prettier 则集来生成,项目看看区别(只有 extends 配置有区别,其它都一样):

extends: [
    'plugin:vue/vue3-essential',
    'eslint:recommended',
    '@vue/typescript/recommended'
]
extends: [
    'plugin:vue/vue3-essential',
    '@vue/standard',
    '@vue/typescript/recommended'
]
extends: [
    "plugin:vue/vue3-essential",
    "eslint:recommended",
    "@vue/typescript/recommended",
    "plugin:prettier/recommended",
]

选择何时进行代码检测

Pick additional lint features:
  Lint on save // 保存就检测
  Lint and fix on commit // fix和commit时候检查

vite cli

下一代前端开发与构建工具,区别于 vue cli 使用的 vebpack,create-vite 在 dev server 使用原生 esm 运行时打包,生产则使用 rollup。
支持 react、vue 框架,这里主要以 vue 举例。

create-vite 此脚手架官方可选模板并没有像 vue cli 那样可选集成了 eslint(包含 vuex、vue-router 都需要自己后续手动集成)

yarn create vite my-vue-app --template vue-ts

至此一个极为简单的 vite 版的 vue 项目就创建完了,接下来集成 eslint。

分析集成 eslint

为了方便理解,先一步一步的按照思路进行配置,否则请直接看下一步的完整配置 eslint。
推荐配置:vite+vue3+ts+prettier 的规则校验。

1、安装 eslint
安装 eslint,并初始化配置文件。

yarn add --dev eslint

创建 eslint 的配置文件.eslintrc.js内容如下,也可以用命令创建npm init @eslint/config

module.exports = {
  root: true,
  env: {
    node: true,
  },
  extends: ["eslint:recommended"],
  parserOptions: {
    ecmaVersion: "latest",
  },
  rules: {},
};

2、添加执行脚本
在 package.json的scripts属性 添加如下:

"lint": "eslint --cache --max-warnings 0  \"src/**/*.{js}\""

然后执行npm run lint
就可以检查src目录下的js文件了。
比如,rules可以设置缩进为2个空格,然后在js里故意缩进3个空格,看看是否报错。

3、支持typescript
eslint默认解析器espree 只能解析 js 文件。
安装eslint的ts相关支持包

yarn add --dev @typescript-eslint/eslint-plugin @typescript-eslint/parser

然后在eslint的配置文件,增加 parser 字段, 添加如下代码

parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
extends: [
  ...
  "plugin:@typescript-eslint/recommended"
]

将执行命令修改,添加.ts文件的检测

"lint": "eslint --cache --max-warnings 0  \"src/**/*.{js,ts}\""

4、支持vue
截至目前,vue文件还不能被eslint检测。
来让其支持,安装依赖

yarn add --dev eslint-plugin-vue

之前解析器需要指定为vue,然后将之前的ts挪到解析配置项中,并添加extends,具体如下

parser: 'vue-eslint-parser',
parserOptions: {
  ...
  parser: "@typescript-eslint/parser",
},
extends: [
  ...
  "plugin:vue/vue3-recommended",
],

将执行命令修改,添加.vue文件的检测

"lint": "eslint --cache --max-warnings 0  \"src/**/*.{js,ts,vue}\""

5、支持prettier
安装依赖

yarn add --dev prettier eslint-config-prettier eslint-plugin-prettier

然后在eslint的配置文件, extends 字段, 添加如下代码

"plugin:prettier/recommended",

配置prettier,prettier.config.js

module.exports = {
  semi: true, // 句尾添加分号
  vueIndentScriptAndStyle: true, // 是否给vue中的 <script> and <style>标签加缩进
  singleQuote: true, // 使用单引号代替双引号
  trailingComma: 'none', // 选项:none|es5|all, 在对象或数组最后一个元素后面是否加逗号
  singleAttributePerLine: true, // HTML、Vue 和 JSX 中有多个属性时,会触发换行
  bracketSameLine: true // 处理singleAttributePerLine闭合标签也会独占一行问题
};

6、配置自定义规则 在eslint的配置文件,增加 rules

rules: {
    'prettier/prettier': 'error',
    'no-var': 'error', // 禁止使用var
    // ---vue-eslint参考:https://eslint.vuejs.org/rules---
    'vue/attribute-hyphenation': ['error', 'always'], // vue模板属性中划线
    'vue/name-property-casing': ['error', 'PascalCase'], // vue组件名规范
    'vue/component-name-in-template-casing': ['error', 'kebab-case'], // vue模板使用组件名规范
    'vue/html-self-closing': [
      'error',
      {
        html: {
          void: 'always'
        }
      }
    ], // 强制自闭合标签
    // ---tslint 规则集参考:https://typescript-eslint.io/rules---
    '@typescript-eslint/no-explicit-any': 'warn', // 允许使用any类型,但是警告(默认即使警告,可以不用声明)
    '@typescript-eslint/no-var-requires': 'warn', // 允许使用require,但是警告(默认不允许)
    '@typescript-eslint/no-empty-function': 'off', // 允许空方法,因为可能是做单例限制构造or被注解修饰的空方法(默认为error)
    '@typescript-eslint/ban-ts-comment': 'off', // 允许@ts- 指令的使用,如@ts-nocheck(默认不允许使用)
    '@typescript-eslint/ban-types': [
      'warn',
      {
        extendDefaults: true,
        types: {
          Function: false
        }
      }
    ], // 禁止部分值被作为类型(默认[https://.../ban-types#default-options]全部error,通过types来放开校验)
    '@typescript-eslint/no-non-null-assertion': 'off' // 允许 非空断言操作符(默认为不允许)
    // '@typescript-eslint/explicit-module-boundary-types': 'off'  // 函数必须定义参数类型和返回类型,默认即是关闭校验
  }

完整配置 eslint

module.exports = {
  root: true,
  env: {
    'vue/setup-compiler-macros': true, // 处理error ‘defineProps’ is not defined no-undef
    node: true
  },
  parser: 'vue-eslint-parser',
  parserOptions: {
    ecmaVersion: 'latest',
    parser: '@typescript-eslint/parser'
  },
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:vue/vue3-recommended',
    'plugin:prettier/recommended'
  ],
  rules: {
    'prettier/prettier': 'error',
    'no-var': 'error', // 禁止使用var
    // ---vue-eslint参考:https://eslint.vuejs.org/rules---
    'vue/attribute-hyphenation': ['error', 'always'], // vue模板属性中划线
    'vue/name-property-casing': ['error', 'PascalCase'], // vue组件名规范
    'vue/component-name-in-template-casing': ['error', 'kebab-case'], // vue模板使用组件名规范
    'vue/html-self-closing': [
      'error',
      {
        html: {
          void: 'always'
        }
      }
    ], // 强制自闭合标签
    // ---tslint 规则集参考:https://typescript-eslint.io/rules---
    '@typescript-eslint/no-explicit-any': 'warn', // 允许使用any类型,但是警告(默认即使警告,可以不用声明)
    '@typescript-eslint/no-var-requires': 'warn', // 允许使用require,但是警告(默认不允许)
    '@typescript-eslint/no-empty-function': 'off', // 允许空方法,因为可能是做单例限制构造or被注解修饰的空方法(默认为error)
    '@typescript-eslint/ban-ts-comment': 'off', // 允许@ts- 指令的使用,如@ts-nocheck(默认不允许使用)
    '@typescript-eslint/ban-types': [
      'warn',
      {
        extendDefaults: true,
        types: {
          Function: false
        }
      }
    ], // 禁止部分值被作为类型(默认[https://.../ban-types#default-options]全部error,通过types来放开校验)
    '@typescript-eslint/no-non-null-assertion': 'off' // 允许 非空断言操作符(默认为不允许)
    // '@typescript-eslint/explicit-module-boundary-types': 'off'  // 函数必须定义参数类型和返回类型,默认即是关闭校验
  }
};

rules

js/ts 缩进

配置 rules 如下

'indent': 2,

vue 首行缩进

纯靠 Indent 会使得 Vue 设置 Script 标签首层不缩进等问题,所以我们需要使用额外插件规则集

配置 rules 如下: 其中,type 为缩进元素设置,可以设置为空格数或者“tab”,这里设置为 2,表示一个缩进为 2 个空格。然后将 baseIndent 设置为 1,表示整体移动一个缩进(表示上面设置的 2 个空格)

'vue/script-indent': ['error', 2,
    {
    'baseIndent': 1,
    }
]

为了避免同时受到 indent 规则的影响,所以我们需要额外配置 overrides 排除忽略属性
对于匹配 overrides.files 且不匹配 overrides.excludedFiles 的 文件,overrides.rules 中的规则会覆盖 rules 中的同名规则。

overrides: [
  {
    files: ["*.vue"],
    rules: {
      indent: "off",
    },
  },
];

最终效果如下

vue 模板属性中划线

必须用中划线,不可用驼峰。
此规则强制在 Vue 模板中的自定义组件上使用带连字符的属性名称。 配置 rules 如下:

"vue/attribute-hyphenation": ["error", "always", {
    "ignore": []
}]

vue 模板属性换行

在 JavaScript 中,将具有多个属性的对象拆分为多行被广泛认为是一种很好的约定,因为它更容易阅读。我们的模板和 JSX 应该得到同样的考虑。---官网
(其实我并不喜欢,因为页面会变得冗长和丑)

配置 rules 如下: 单行的时候可接受的属性个数 1,存在手动换为多行的时候 支持每行属性个数也是 1。这也是默认设置

"vue/max-attributes-per-line": ["error", {
    "singleline": 1,
    "multiline": 1
}]

但是效果如上,并不好,存在以下问题:

  • 多行属性对齐问题,没有以组件位置为 base
  • 当标签上属性>1 的时候,第一个属性也应该换行,实际上没有

所以引出了另一个配置,配置 rules 如下: 单行属性时,第一个属性的位置不用换行,多行就必须要换行.
更优秀的是它顺带处理了多行属性对齐基准问题

"vue/first-attribute-linebreak": ["error", {
    "singleline": "ignore",
    "multiline": "below"
}]

Prettier

如上规则,其实完成一个优秀的 eslint 配置 还需要几十个甚至上百个规则配置,实在麻烦。
于是大家都使用了预设的规则集 Prettier。

安装使用

需要安装两个依赖(假设你没用脚手架预设)

yarn add --dev eslint-plugin-prettier eslint-config-prettier

eslint-plugin-prettier:这是一个 ESLint 插件,这意味着它包含 ESLint 将检查的其他规则的实现。这个插件在引擎盖下使用了 Prettier,当您的代码与 Prettier 的预期输出不同时,会引发问题。这些问题可以通过--fix 自动修复。使用这个插件,您不需要单独运行 prettier 命令,该命令将作为插件的一部分运行。此插件不会关闭与格式相关的规则,如果您手动或通过 eslint-config-prettier 发现此类规则的冲突,则需要将其关闭。

eslint-config-prettier:这是一个 ESLint 配置,它包含规则的配置(无论某些规则是开启,关闭还是特殊配置)。通过此配置,您可以通过关闭与 Prettier 冲突的格式相关规则,将其与其他 ESLint 配置一起使用,例如 eslint-config-airbnb。使用此配置,您不需要使用 prettier-eslint,因为在 Prettier 格式化代码后,ESLint 不会抱怨。但是,您需要单独运行 prettier 命令。

extends: [
    ...
    "plugin:prettier/recommended"
]

完成如上配置即可。 通常情况下,默认的 prettier 规范已够我们使用,如果需要调整,直接修改 prettier.config.js 配置文件即可。

推荐 eslint 配置

module.exports = {
  root: true,
  env: {
    node: true,
  },
  extends: [
    "plugin:vue/vue3-essential",
    "eslint:recommended",
    "@vue/typescript/recommended",
    "plugin:prettier/recommended",
  ],
  parserOptions: {
    ecmaVersion: 2020,
  },
  rules: {
    "no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
    "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
    "prettier/prettier": "error",
  },
};