四、在 Vue 项目中的配置
仅以 Vue3 + TS 为例。
- 在进行此步骤时,请在 settings.json 中把第二节的 Prettier 单引号格式化关闭,避免与项目设定产生冲突。
- 在 VSCode 中安装插件:Vue Language Features (Volar),给 Vue 提供代码高亮和语法提示。
- 在 VSCode 中安装插件:ESLint,这样代码不规范的时候底部才有波浪线出现。
4.1 使用 create-vue 创建 Vue 项目
打开命令行终端,按照官网提示,执行:npm init vue@latest
注意,最后两项(ESLint、Prettier)需要选上。
从 package.json 中能够看到 eslint 和 prettier 的相关依赖已经被添加到开发依赖中:
打开项目中的 .eslintrc.cjs 文件(ESLint 配置文件):
/* eslint-env node */ require("@rushstack/eslint-patch/modern-module-resolution"); module.exports = { root: true, extends: [ "plugin:vue/vue3-essential", "eslint:recommended", "@vue/eslint-config-typescript/recommended", "@vue/eslint-config-prettier", ], parserOptions: { ecmaVersion: "latest", }, overrides: [ { files: ["cypress/e2e/**.{cy,spec}.{js,ts,jsx,tsx}"], extends: ["plugin:cypress/recommended"], }, ], };
这是 create-vue 脚手架官方默认配置好的 eslint 配置文件,我们从这里启程。
可以看到导出的对象中有这么几个字段:
- root
- extends
- parserOptions
- overides
这些是 eslint 的配置项,分别来看看他们有什么作用。
4.1.1 root
module.exports = { root: true, // others };
root:是否以当前目录为根目录。 告诉 ESLint 不要再往上级目录查找,利用此属性配置,项目级和目录级的配置都可以不受上级目录以及祖先目录的配置影响,通常项目根目录应该设置为 true
。
举个例子,比如这个项目 vue-project1,默认情况下 root 为 false,而且该项目上层目录下还有 eslint 配置文件的话,这个更上一层的配置就会对你的项目文件的代码产生作用,直到到达根目录才会停止。这是我们不愿意看到的,所以就需要我们在当前项目目录下设置 root: true,告诉 ESLint 这里就是根目录了,别再往上查找其他的配置文件了!
官网上还讲了 .eslintrc.*
文件或 package.json
文件中的 eslintConfig
字段在不同层级的作用关系,感兴趣的可以去看一下:eslint.org/docs/latest…
4.1.2 extends && rules
module.exports = { extends: [ "plugin:vue/vue3-essential", "eslint:recommended", "@vue/eslint-config-typescript/recommended", "@vue/eslint-config-prettier", ], // others }
eslint.org/docs/latest…
extends:ESLint 扩展配置。 ESLint 是根据一批规则(rules)来检验代码质量的,比如上面的 eslint:recommended
被加入到 extends 后,代码质量检查的时候就会使用这套规则:eslint.org/docs/latest…
对于 Vue 项目来说,仅使用官方提供的规则显然是不够或者存在冲突。所以,你会发现还有诸如:plugin:vue/vue3-essential
、@vue/eslint-config-typescript/recommended
、@vue/eslint-config-prettier
等规则。它们在数组中的顺序是有讲究的,后一个配置将会继承它前面的配置,然后将这些共享配置扩充为一套符合项目要求的完整规则。
plugin:vue/vue3-essential
:Vue.js 的官方 ESLint (规则)插件。Official ESLint plugin for Vue.js. This plugin allows us to check the<template>
and<script>
of.vue
files with ESLint, as well as Vue code in.js
files.
@vue/eslint-config-typescript/recommended
:专门给 Vue 使用的 TS 验证规则(eslint-config-typescript
)。This ruleset is the base configuration for Vue-TypeScript projects. Besides setting the parser and plugin options, it also turns off several conflicting rules in theeslint:recommended
ruleset. So when used alongside other sharable configs, this config should be placed at the end of theextends
array.
- 安装:www.npmjs.com/package/@vu…
- 规则列表:typescript-eslint.io/rules/
@vue/eslint-config-typescript
有两套规则集,一个是@vue/eslint-config-typescript
,一个就是@vue/eslint-config-typescript/recommended
。其中,后者更加严格。- 这个扩展还提到了
@rushstack/eslint-patch
,它是用来解决 ESLint 的一个已知的限制的,按照 README 配置就行。 - 另外,和其他共享配置放在一起时,该配置需要放在 extends 数组的最后,但要放在 prettier 配置之前。
@vue/eslint-config-prettier
:专门给 Vue 使用的 Prettier 验证规则(eslint-config-prettier
)。作用:关闭所有不需要的、或者可能与 Prettier 产生冲突的 eslint 规则。
- 需要确保 ESLint 和 Prettier 都已经安装。
- 安装:www.npmjs.com/package/@vu…
- 它应该被放在 extends 数组的最后而覆盖其他配置,这样就能完全关闭 ESLint 规则集中与格式化代码相关的规则,好让 Prettier 单独去做代码格式化的工作。
补充:eslint-config- 作为前缀可以省略。例如:
@vue/eslint-config-typescript/recommended
等价于:@vue/typescript/recommended
eslint-config-airbnb
等价于:airbnb
- ……
4.1.3 parserOptions
module.exports = { parserOptions: { ecmaVersion: "latest", }, // others }
eslint.org/docs/latest…
parserOptions:解析器选项,允许你指定 JS 语言(包括 JSX 语法),默认为 ES5。
- 配置文件中,用到了 ecmaVersion 这个选项,指定了检测的版本为
latest
,这样就能支持最新的语法的解析,不然检测新语法就会报错。 - 如果要检测 React 项目中的 JSX 语法,给 ecmaFeatures 添加
jsx: true
是不推荐的,要用专门的 eslint-plugin-react 。
4.1.4 overrides
module.exports = { overrides: [ { files: ["cypress/e2e/**.{cy,spec}.{js,ts,jsx,tsx}"], extends: ["plugin:cypress/recommended"], }, ], // others }
overrides:用指定配置覆盖指定后缀的文件的规则配置。 这里是用 plugin:cypress/recommended
这个规则集对cypress/e2e/**.{cy,spec}.{js,ts,jsx,tsx}
这些后缀文件进行代码检查。
- overrides[].files:数组,指定文件
- overrides[].extends:数组,指定规则集
4.1.5 env
/* eslint-env node */
eslint.org/docs/latest…
在 .eslintrc.cjs 的最顶部有这么一行注释,它的作用是:指定源代码所处的环境,以便于 ESLint 知道所使用的全局变量是在这些环境下存在的,这样就不会因为一些规则而报错。此处的 env 被设置为 node,于是使用 global 这个全局变量就不会报未定义的错误了。
类似的,browser
环境下有 window
全局变量,jQuery
环境下有 $
全局变量,es6
环境下有 Set
等新特性全局变量。 如果在 node
环境下使用 window
变量 ESLint 就会报错。
除了写注释,还可以写在返回的对象里,像这样:
module.exports = { env: { node: true, } // others }
4.1.6 小节
以上,我们分析了 create-vue 脚手架的 eslint 配置,提到了eslint配置文件中的几个配置项(root
, extends
, parserOptions
, overrides
, env
),除了这些,其实还有其他的配置项,例如:rules
, plugins
等等,还有配置文件的不同形式,脚本执行 lint 命令等等,这些将在后面继续分析。
4.2 使用 Vue CLI 创建 Vue 项目
官方推荐使用 create-vue 的形式创建 Vue 项目,所以 Vue CLI 这种方式估计会逐步废弃。
打开命令行终端,按照官网提示,
先安装脚手架: npm install -g @vue/cli
再创建项目: vue create vuecli-project1
package.json 中有关 eslint 和 prettier 的依赖:
打开 .eslintrc.js 文件:
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", }, };
这时候,再看这些代码应该不再那么陌生了,root
, env
, extends
, parserOptions
都是熟悉的身影。
4.2.1 rules
module.exports = { rules: { "no-console": process.env.NODE_ENV === "production" ? "warn" : "off", "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off", }, // ... };
eslint.org/docs/latest…
想要对某些规则进行修改,就要用到 rules 了。
- 如果要关闭该规则,则设置为 off 或 0;
- 如果打开该规则并触发警告,则设置为 warn 或 1;(不会让程序退出)
- 如果打开该规则并提示错误,则设置为 error 或 2。(会让程序退出)
例如,no-console 规则是不允许使用 console,上面设置后就会在生产模式下打开规则并触发警告,在其他模式下关闭该规则。
如果该规则存在多个选项,比如 quotes,则使用数组存放:
module.exports = { rules: { "quotes": ["error", "double"] // 引号规则:引号要用双引号,不符合规则就报错 }, // ... };
4.2.2 令人费解的 extends 与 plugins
从头到尾都没见到 plugins
的踪影,太奇怪了,这在 ESLint 官网是有专门一个章节介绍的,别急,马上破案。
配置文件中的 extends 中出现了 plugin:prettier/recommended
,还有一个 plugin:vue/vue3-essential
,它们看起来有类似的结构,都是以 plugin 开头,这和 plugins 有什么关联吗?
确实是有关联的,你可能永远不(令)会(人)想(费)到(解),plugin:prettier/recommended
等价于下面这套配置:
{ "extends": ["prettier"], // 等价于 eslint-config-prettier "plugins": ["prettier"], // 等价于 eslint-plugin-prettier "rules": { "prettier/prettier": "error", "arrow-body-style": "off", "prefer-arrow-callback": "off" } }
除非你看 github 文档。另外,extends
中的 prettier
是 eslint-config-prettier
的简写,plugins
中的 prettier
是 eslint-plugin-prettier
的简写,这就和开发依赖对应上了。
这两个包的区别在正文第三部分的第三小节提到了。简言之,前者关闭 eslint 中和 prettier 冲突的规则,是放在 extends
中的;后者将 prettier 的格式化问题当作 eslint 的规则进行检测,出错时作为 error 抛出,是放在 plugins
中的。
同理,plugin:vue/vue3-essential
也是某种合并写法,它对应的开发依赖是 eslint-plugin-vue
。
@vue/typescript/recommended
对应的开发依赖是 @vue/eslint-config-typescript
,其中 eslint-config-typescript
简写为 typescript
,使用的是建议的(recommended
)规则集。
4.2.3 小节
以上,我们介绍了 rules
和 plugins
,如果你想要微调规则,那么就在 rules
里改吧;如果你找不到 plugins
就去 extends
里找找吧。
4.3 使用 Vite 创建 Vue 项目 —— 自行配置 ESLint + Prettier
打开命令行终端,按照官网提示,执行:npm create vite@latest
从 package.json 中可以看出,使用 vite 搭建项目比较“干净”,常用的开发依赖需要我们自行配置:
那么怎么配置呢?很简单,分析了 create-vue 和 Vue CLI 的方式后,相信你知道怎么做了。答案就是根据之前的配置照猫画虎~
4.3.1 安装 Prettier
格式化部分使用 Prettier。
- 安装,在终端里输入以下命令:
npm install --save-dev --save-exact prettier
添加配置文件 .prettierrc.json
echo {}> .prettierrc.json
在 .prettierrc.json 中添加常用的格式化配置,IDE 会自动检测到它们:
{ "semi": false, "singleQuote": true }
比如,添加了两个格式化规则:
4.3.2 安装 ESLint
代码质量检测部分使用 ESLint,还有 Vue 专用的插件。
- 安装,在终端里输入以下命令:
npm install --save-dev eslint eslint-plugin-vue
在项目根目录下添加配置文件 .eslintrc.cjs(后面需要使用到 CommonJS 的语法,所以这里使用 .cjs 为后缀的文件,否则会报错。)
module.exports = { env: { node: true, }, extends: [ 'eslint:recommended', 'plugin:vue/vue3-recommended', ], rules: { // override/add rules settings here, such as: // 'vue/no-unused-vars': 'error' } }
4.3.3 添加 Prettier 扩展配置
安装 Vue 专用的 prettier 扩展配置 :
npm install --save-dev @vue/eslint-config-prettier @rushstack/eslint-patch
在配置文件 .eslintrc.cjs 中添加配置:
require("@rushstack/eslint-patch/modern-module-resolution") module.exports = { env: { node: true, }, extends: [ 'eslint:recommended', 'plugin:vue/vue3-recommended', "@vue/eslint-config-prettier" ], rules: { // override/add rules settings here, such as: // 'vue/no-unused-vars': 'error' } }
上面有的字符串用的是单引号,有的则是双引号,在刚刚复制过去时,一定会被 prettier 检测出来问题,就像这样:
按照 .prettierrc.json 里添加的格式化规则,应当使用单引号包裹字符串。此时,只要正常保存,就能自动修复问题了。
完成!
然而上面其实存在一个疑点——为什么只是安装了 @vue/eslint-config-prettier
,格式化问题部分会出现波浪线提示?明明没有安装 eslint-plugin-prettier
!
实际上,在 [@vue/eslint-config-prettier](<https://www.npmjs.com/package/@vue/eslint-config-prettier>)
的官网已经给出了提示,只是我们一般不仔细看:
为了进一步验证,我在 node_modules 目录中翻出了 @vue/eslint-config-prettier
的依赖项,eslint-plugin-prettier
正躺在里面睡觉……
所以,不需要重复安装和配置 eslint-plugin-prettier
,不然你会怀疑人生。在写这篇文章的时候,这个坑我爬过。