团队协作(一)—— 你不知道的 ESLint + Prettier

参考:

一、前言

这是团队协作系列的第一篇,字数 8000+,长文警告 ⚠

有经验的工程师应该了解,开发一个项目前我们需要一份团队开发规范,以此为共识,共同构建我们的项目开发。

去年公司的一个项目需要重构,为什么需要重构?除了产品设计发生变化以外,前端的 UI 样式发生了大变革。产品设计的变化意味着功能的变动,我们要对功能代码进行调整;UI 的大变革体现在高度定制化,我们需要构建一个自己的组件库。作为团队新人,在我看到项目代码,尤其让我印象深刻的是,核心代码无注释、ES6 使用较少、变量命名无章法、文件结构组织混乱、组件封装性有待提高…… 以上想必也是大部分工程师面临的困境……

需要做的事情很多,但古语有云:“三军未动,粮草先行”。面对上述诸多问题,我查阅了很多资料、与很多大佬交流,起草并拉着团队成员制定了第一版前端开发规范,再拉会宣讲、统一团队认知,对内在开发规范层面达成共识,对外展现我们是会思考、有保障的工程师。

本着“取其精华,去其糟粕”的原则,在进行开发工作的过程中,我们对规范进行了适当补充和删减,不断反馈和完善,当然过程非常艰辛。就这样,在大家的共同努力下,代码质量得到了显著提升。

1.1 文档类规范的局限性

在这个项目上的试验成功以后,我准备将这套规范推广到更多项目,正巧那时我已开始负责公司所有的前端开发管理工作。但是遇到了很多问题,其中明显感觉心有余而力不足的一点是,随着项目需要团队开始扩充人数,然而绝大多数都是实习生,这意味着我需要在实习生培养与不同项目开发之间达到动态平衡。实习生没有太多开发经验,对于开发规范的理解相对是有难度的,我想要通过 Code Review 来保证代码质量以及最佳实践的引导和传授。事实证明这很难,我不得不花费大量精力保证代码质量和风格,并且有时迫于紧张的工期压力,没有办法全身心地关注实习生的每一次 pull request,于是只好抓大放小。逐渐地,我发现即便是有文档,也很难实现代码风格的同步,散落在项目代码中的“不规范代码”在将来会产生巨大的隐患,比如:“make a shit mountain of code”。

1.2 团队组织的合作问题

1999 年 9 月 23 日,NASA 发射的火星探测器到达火星,准备执行任务,但与地面失联。按照原计划早就重新绕到火星前面,但地面无信号。最后发现是因为负责制造推进器的公司和负责制造中央处理器的公司采用了不同的单位,力学单位换算出错,最后引发了这场坠毁事故,可想而知这样的代价多么高昂……

NASA 曾经因为力学单位不一致遭受严重的损失。对于团队组织来说,如果开发规范不统一,意味着整体步调不一致,合作将受阻,最后引发一系列问题。为什么呢?站在 10 人以内团队管理经验的角度下,我认为至少存在以下 6 种可能性:

第一、存在不同成员需要开发同一个项目的可能性;

第二、存在不同成员需要维护不属于自己那部分代码的可能性;

第三、存在不同成员需要同时开发一个模块的可能性;

第四、存在不同成员需要同时兼顾不同项目开发的可能性;

第五、存在不同成员使用不同 IDE 的可能性;

第六、存在异地团队协同开发的可能性。

如果不统一开发规范,短期来看,好像开发得更加迅速,可以更快推出产品。但长期来看,以上六点叠加的,不管是技术上还是管理上,它们附带的显性的或者是隐患的成本都极其高。

1.3 使用工具的本质

所以,基于以上两大问题,如何统一开发规范就成了关键问题。ESLint + Prettier (+ editorconfig + husky + commitlint) 这套工具组合可以说是神技了,可以在一定程度上实现代码层面的自动化,至少可以完成团队层面的代码规范统一(代码逻辑仍然需要有经验的工程师进行 Code Review)。这种统一工作表面上是在增加开发人员的心智负担,看上去还和业务没有任何关系,但本质上却提升了代码质量,在测试之前就减少了大量的 bug,在测试之后,减少了代码维护成本和后续开发的认知成本。如此一来,让产品稳定上线,提升用户使用体验,为业务发展保驾护航。否则是在浪费时间,我依稀还记得那一次我花了 3 个多小时合并代码的窘境和痛苦……

在设置 ESLint 和 Prettier 之前,要知道它们是什么,我的概括如下:

ESLint 是什么?检测 JS 代码,发现代码质量问题并修复问题,还可以自己根据项目需要进行规则的自定义配置以及检查范围等等。

Prettier 是什么?代码格式化工具,可以让团队的代码风格保持一致。可支持的源码类型包括:JavaScript, JSX, Angular, Vue, Flow, TypeScript, CSS, HTML, JSON, YAML……

简单来说,前者用于代码潜在问题的发现,后者用于代码风格的保持。

我不准备根据官方文档娓娓道来,而是通过几个常用的脚手架工具直接让大家上手体验效果。

二、浅尝 Prettier

以 VSCode 为 IDE,需要安装好 Prettier 扩展插件。

image.png

2.1 设置:保存时格式化

在设置中搜索找到 Editor: Format On Save,勾选它:

image.png

勾选之后,通过 Ctrl+Shift+P 搜索找到 settings.json

image.png

点击进入后可以看到最下方新增了一条 VSCode 配置设定: "editor.formatOnSave": true,

image.png

设置完成后,当你在保存文件时,VSCode 就可以帮你进行格式化了。到这你一定有疑惑,VSCode 根据什么来格式化?是的,格式化的形式需要你自己选择。别担心,这个后面我会提到,go on。

2.2 在 VSCode 中使用 Prettier

打开设置找到 Prettier: Single Quote,勾选它:

image.png

同理, settings.json 新增了一条 VSCode 配置设定:"prettier.singleQuote": true,

image.png

在前言部分提到,Prettier 是用来保持代码风格的,使用单引号而非双引号就是一种代码风格。在勾选了这个设定以后。找个目录,新建一个 index.js:

const express=require("express");

第一行中就用了双引号,当保存时就会应用 2.1 部分的自动格式化,将双引号修复为单引号。

现在按下保存键试试,会有通知提示你需要进行配置

image.png

点进去,选择 Prettier-Code formatter 即可 (其他前端相关的代码也选择 Prettier 插件即可)

image.png

基本可以猜到,只要是有关 VSCode 的配置都会在你设置后,让 settings.json 新增一条相关配置:

image.png

再次保存,你会发现修复好了。

image.png

注意,这里的修复不仅是引号问题被格式化修复,赋值号的前后添补了空格,原因在于 Prettier 作为 VSCode 的插件,它自带有一套默认的代码风格配置。

在哪里看配置?新建终端 ⇒ 左边找到【输出】tab ⇒ 右边找到 Prettier。

image.png

在上面的截图中,除了 Prettier Options,还有

  • 检测 ignore file( .prettierignore) 是否存在
  • 检测本地配置文件( .prettierrc or .editorconfig)是否存在

好了,此处又可以猜到检测的目的。如果既安装了插件又存在忽略文件或者配置文件,那么 VSCode 插件的权重则更低,也就是会被本地配置文件覆盖。

在 github 上验证了这个猜想是正确的:github.com/prettier/pr…

image.png

从优先级可以看出,对于团队项目开发来说,使用 prettier configuration file 更为实际。另外,理解这个优先级是非常重要的。在项目中,如果你发现配置的和你预想的不一样,你就要想想看是不是这三处冲突了,因为他们是可以并存的。

三、为什么是 ESLint + Prettier

在前言中提到,ESLint 是用于发现并修复代码问题(包括代码风格格式化),这和 Prettier 美化代码风格显得很矛盾,因为它们存在重叠的部分,那么业界为什么要将二者结合在一起使用呢?

3.1 疑惑一

一开始我是很疑惑的,后来在 Prettier 的官方文档中找到如下解释,让我有点豁然开朗:prettier.io/docs/en/com…

image.png

ESLint 对于代码问题的检测采用两类规则,一类是格式化规则,一类是代码质量规则。前者与 Prettier 做的事情是一致的,因此,我们通过 Prettier 执行格式化代码的工作,而代码质量的控制由 ESLint 处理。换句话说,前者美化代码,后者捕获 bugs。

3.2 疑惑二

那么问题又来了,既然 ESLint 可以把事情全都做了,为什么不直接用 ESLint?这个问题困扰我很久,我的字节朋友(强哥)给了我答案: ESLint 之类的 Linters 对于代码格式化的能力是有限的,不如 Prettier 那么专业,这是常见的二者冲突问题。

3.3 疑惑三

所以,怎么处理重叠部分的冲突?Prettier 提供了两个插件:

  • eslint-config-prettier

    • github.com/prettier/es…
    • 解决 ESLint 中的样式规范(即代码风格)和 Prettier 中样式规范的冲突,以 Prettier 的样式规范为准,使 ESLint 中的样式规范自动失效。对应 .eslintrc 配置 extends-"prettier"
  • eslint-plugin-prettier

    • github.com/prettier/es…
    • 将 Prettier 样式规范作为 ESLint 代码质量规范来使用,同样将格式问题以 error 的形式抛出,即 rule-"prettier/prettier",可在 rules-"prettier/prettier" 中进行自定义配置。对应 .eslintrc 配置 plugin-"prettier"

四、在 Vue 项目中的配置

仅以 Vue3 + TS 为例。

  • 在进行此步骤时,请在 settings.json 中把第二节的 Prettier 单引号格式化关闭,避免与项目设定产生冲突。

    image.png

  • 在 VSCode 中安装插件:Vue Language Features (Volar),给 Vue 提供代码高亮和语法提示。

  • 在 VSCode 中安装插件:ESLint,这样代码不规范的时候底部才有波浪线出现。

4.1 使用 create-vue 创建 Vue 项目

打开命令行终端,按照官网提示,执行:npm init vue@latest

image.png

注意,最后两项(ESLint、Prettier)需要选上。

package.json 中能够看到 eslintprettier 的相关依赖已经被添加到开发依赖中:

image.png

打开项目中的 .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…

image.png

对于 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 the eslint:recommended ruleset. So when used alongside other sharable configs, this config should be placed at the end of the extends 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。

image.png

  • 配置文件中,用到了 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 这种方式估计会逐步废弃。

image.png

打开命令行终端,按照官网提示,

先安装脚手架: npm install -g @vue/cli

再创建项目: vue create vuecli-project1

image.png

package.json 中有关 eslint 和 prettier 的依赖:

image.png

打开 .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…

image.png

想要对某些规则进行修改,就要用到 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 中的 prettiereslint-config-prettier 的简写,plugins 中的 prettiereslint-plugin-prettier 的简写,这就和开发依赖对应上了。

image.png

这两个包的区别在正文第三部分的第三小节提到了。简言之,前者关闭 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 小节

以上,我们介绍了 rulesplugins,如果你想要微调规则,那么就在 rules 里改吧;如果你找不到 plugins 就去 extends 里找找吧。

4.3 使用 Vite 创建 Vue 项目 —— 自行配置 ESLint + Prettier

打开命令行终端,按照官网提示,执行:npm create vite@latest

image.png

package.json 中可以看出,使用 vite 搭建项目比较“干净”,常用的开发依赖需要我们自行配置:

image.png

那么怎么配置呢?很简单,分析了 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'
      }
    }
    
  • eslint-plugin-vue 的规则:eslint.vuejs.org/rules/

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 检测出来问题,就像这样:

image.png

按照 .prettierrc.json 里添加的格式化规则,应当使用单引号包裹字符串。此时,只要正常保存,就能自动修复问题了。

image.png

完成!

然而上面其实存在一个疑点——为什么只是安装了 @vue/eslint-config-prettier ,格式化问题部分会出现波浪线提示?明明没有安装 eslint-plugin-prettier

实际上,在 [@vue/eslint-config-prettier](<https://www.npmjs.com/package/@vue/eslint-config-prettier>) 的官网已经给出了提示,只是我们一般不仔细看:

image.png

为了进一步验证,我在 node_modules 目录中翻出了 @vue/eslint-config-prettier 的依赖项,eslint-plugin-prettier 正躺在里面睡觉……

image.png

所以,不需要重复安装和配置 eslint-plugin-prettier ,不然你会怀疑人生。在写这篇文章的时候,这个坑我爬过。

4.3.4 添加 TypeScript 扩展配置

这是一个 Vue3 + TS 的项目,当然还需要检测 TS 语法。

image.png

打开 HelloWorld.vue 就发现了 TS 相关的错误。

安装 Vue 专用的 TS 扩展配置:

npm install --save-dev @vue/eslint-config-typescript @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-typescript/recommended',
    '@vue/eslint-config-prettier',
  ],
  rules: {
    // override/add rules settings here, such as:
    // 'vue/no-unused-vars': 'error'
  },
}

注意,始终让 prettier 相关配置留在 extends 数组的最后一位。

之后,问题解决:

image.png

4.3.5 其他配置添加

在 .eslintrc.cjs 中添加了几个常见配置:

require('@rushstack/eslint-patch/modern-module-resolution')

module.exports = {
  env: {
    node: true,
		browser: true,
		es2021: true,
  },
	parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
  },
  extends: [
    'eslint:recommended',
    'plugin:vue/vue3-recommended',
    '@vue/eslint-config-typescript/recommended',
    '@vue/eslint-config-prettier',
  ],
  rules: {
    // override/add rules settings here, such as:
    // 'vue/no-unused-vars': 'error'
  },
}

在 .prettierrc.json 中添加了几个常见规则:

{
  "semi": false,
  "singleQuote": true,
  "tabWidth": 2,
  "useTabs": false,
  "bracketSpacing": true
}

4.3.6 添加终端命令

除了在配置文件中加入相关配置,命令行也可以。

在 package.json 中的 script 中添加两条命令:

"lint": "eslint --ext .js,.ts,.vue --ignore-path .gitignore --fix src",
"format": "prettier . --write --ignore-path .gitignore"

4.3.7 使用终端命令

现在尝试运行 npm run lint 来检测和修复代码:

image.png

vite-env.d.ts 出现了 3 个问题,2 个错误和 1 个警告。

针对这些问题,按照给出的提示,做对应调整就行。

或者调整 .eslintrc.cjs 的规则细节:

require('@rushstack/eslint-patch/modern-module-resolution')

module.exports = {
  // other options
  rules: {
    // override/add rules settings here, such as:
    // 'vue/no-unused-vars': 'error'
    '@typescript-eslint/ban-types': [
      'error',
      {
        extendDefaults: true,
        types: {
          '{}': false,
        },
      },
    ],
    '@typescript-eslint/no-explicit-any': 0,
  },
}

之后,再次运行就不会报错了。

现在把 App.vue 文件中的代码格式打乱,变成屎山风格:

image.png

运行 npm run format 来格式化代码,摇身一变大漂亮:

image.png

4.3.8 小节

以上,我们自行配置了 ESLint + Prettier,可以实现保存时,根据配置的规则,自动检查并修复代码。另外一方面,可以通过命令行来实现相关流程。

那么问题来了,既然我们已经给 VSCode 设置了保存时自动修复,那么为什么还要设置命令行相关命令呢?这个问题和 CI 有关,我先挖个坑留着。(这篇实在太长了,如果你能看到这,我得给你赞哈哈哈)

五、总结

在 Vue3 + TS 项目中配置 ESLint + Prettier 基本就是这些内容了,更多的细节可以自己去查阅官网。接下来,整理一下整个流程:

如果你不想自己手动配置,那么就使用 create-vue 脚手架来自动添加 ESLint + Prettier 吧,或者使用ESLint 初始化 npm init @eslint/config

如果你想要自己配置,那么就使用 Vite 来创建项目,然后按照以下步骤来配置:

  1. 在 IDE 中添加 ESLint、Prettier 插件,并设置保存时自动修复;
  2. 使用 vite 搭建脚手架,以此为基点,安装并配置 prettier ,安装并配置 eslint;
  3. 在 eslint 配置文件中,添加 prettier 和 typescript 相关扩展配置;
  4. 分别添加 lint 和 format 的终端命令。

另外,我还想补充或强调一些重要的 stuff:

  1. ESLint 和 Prettier 都有配置文件,各种类型,但作用是一样的。

    1. Configuration File in ESLint

      image.png

    2. Configuration File in Prettier

      image.png

  2. 相对的,还有一组 Ignoring Code 文件,用来指定不需要检查的文件,也可以使用 CLI 命令 --ignore-path ,在 4.3.6 中有提到。

    1. .eslintignoreeslint.org/docs/latest…
    2. .prettierignoreprettier.io/docs/en/ign…
  3. 优先级问题,配置文件的优先级大于 IDE 的设置(settings.json),建议把设置里的关闭,采用配置文件。

  4. ESLint 的规则(rules)除了在配置文件中设置,还可以通过注释的方式使用:eslint.org/docs/latest…

  5. 局部范围内禁用一部分 ESLint 的规则(rules)的方式:eslint.org/docs/latest…

  6. ESLint 配置文件中的 extends 字段,遇到以 eslint-config- 为前缀的扩展配置,可以省略前缀。例如,eslint-config-prettier 可以简写为 prettier@vue/eslint-config-prettier 可以简写为:@vue/prettier 等等。eslint.org/docs/latest…

  7. 同理,ESLint 配置文件中的 plugins 字段,遇到以 eslint-plugin- 为前缀的插件,也可以省略前缀。eslint.org/docs/latest…

  8. ESLint 配置文件中,prettier 相关的扩展配置需要放在 extends 数组的最后一位,避免影响格式化。

  9. 在使用 VSCode 时,保存代码时会自动格式化,右下角的通知会提示你选择格式化插件,选 Prettier 即可。

ESLint + Prettier 很好地解决了代码质量检查和格式化的问题,解放了 Code Review 中代码规范方面的巨大压力。1.3 节还提到了 editorconfig + husky + commitlint,至于这些组合为什么出现,将在团队协作系列的下篇剖析,大家敬请期待~

如有疑问,可以添加我的微信:enjoy_Mr_cat,入群沉淀、共同成长。

以上,如有谬误,还请斧正。

最后,希望这篇文章对你有所帮助,感谢您的阅读~

posted @ 2022-08-30 23:19  见嘉于世  阅读(0)  评论(0编辑  收藏  举报  来源