# 静态检查工具

前面的章节讲了很多关于单测和集成测试的内容,它们可以有效地提高我们的代码信心。

不过,不只有写测试才能提高代码信心,我们还能通过静态代码检查工具来实现,比如 TypeScript、ESLint 等。TypeScript 之前已跟大家聊过了, 这章就来讲讲 ESLint。

# ESLint

ESLint (opens new window) 是一个前端标准的静态代码检查工具,它可以根据配置的规则来检查代码是否符合规范。 现在市面上已经有很多 ESLint 相关的规则集,我们只需安装配置它们就好了:

# ESLint
npm i -D eslint@8.13.0
# TypeScript 相关
npm i -D @typescript-eslint/eslint-plugin@5.19.0 @typescript-eslint/parser@5.19.0
1
2
3
4

在项目根目录添加 .eslintrc.js

module.exports = {
  root: true,
  env: {
    browser: true,
    node: true,
  },
  plugins: [],
  extends: [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended",
  ],
  rules: {
    // 关闭规则
    "@typescript-eslint/no-non-null-assertion": "off",
    "@typescript-eslint/no-explicit-any": "off",
  },
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

我们配置的 ESLint 继承了 eslint:recommended 以及 plugin:@typescript-eslint/recommendedESLint 配置

执行 npx eslint src --fix 会自动修复 src 文件下的代码了。

# Prettier

Prettier (opens new window) 是一个代码格式化工具。 前一小节说到 ESLint 是通过制定的的规范来检查代码的,这里的 规范 有两种:

  • 代码风格规范
  • 代码质量规范

Prettier 主要负责的是代码风格。

TIP

绝大多数程序是不会对代码质量规范有异议的,但他们往往很难在代码风格上达成共识。 而代码风格又是一个很主观的东西,公说公有理,婆说婆有理,怎么办呢?

Prettier 就说:别吵了,我来定一个 最完美 的规范,你们就先按我的来,哪条不满意的,再自己配吧。

现在我们来安装一下 Prettier:

# Prettier
npm i -D prettier@2.6.2
# Prettier x ESLint 的配置和插件
npm i -D eslint-config-prettier@8.5.0 eslint-plugin-prettier@4.0.0
1
2
3
4

在根目录添加配置文件 .prettierrc

{}
1

这里我们不修改任何 Prettier 配置。然后在 .eslintrc.js 里引入 Prettier:

module.exports = {
  // ...
  extends: [
    // ...
    "plugin:prettier/recommended",
  ],
};
1
2
3
4
5
6
7

注意:要把 Prettier 的推荐配置 plugin:prettier/recommended 放在 extends 最后一项。

# 写测试的规则

那么代码质量方面呢?著名的有 Airbnb 研发的 eslint-config-airbnb (opens new window) ESLint 配置。 不过,由于这个项目重点在测试,所以我们只关注测试代码的质量就好了。正好 Jest 和 React Testing Library 也推出了自己的 ESLint 规则和配置,我们来安装一下:

# Jest 和 RTL 的
npm i -D eslint-plugin-jest@26.1.4 eslint-plugin-testing-library@5.3.1
1
2

.eslintrc.js 里引入它们,最终 ESLint 的完整配置如下:

module.exports = {
  root: true,
  env: {
    browser: true,
    node: true,
    "jest/globals": true,
  },
  plugins: [],
  extends: [
    // ESLint
    "eslint:recommended",
    // TypeScript
    "plugin:@typescript-eslint/recommended",
    // Jest
    "plugin:jest/recommended",
    // React Testing Library
    "plugin:testing-library/react",
    // Prettier
    "plugin:prettier/recommended",
  ],
  rules: {
    // 关闭规则
    "@typescript-eslint/no-non-null-assertion": "off",
    "@typescript-eslint/no-explicit-any": "off",
    "no-var": "off",
    "@typescript-eslint/no-var-requires": "off",
    "testing-library/no-dom-import": "off",
    // 错误提示
    "jest/no-focused-tests": "error",
    "jest/no-identical-title": "error",
    "jest/valid-expect": "error",
    "testing-library/await-async-query": "error",
    "testing-library/no-await-sync-query": "error",
    // 告警提示
    "jest/no-disabled-tests": "warn",
    "jest/prefer-to-have-length": "warn",
    "testing-library/no-debugging-utils": "warn",
  },
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

有了这种提示,你写测试代码时就会更规范,更少犯错。

# extends vs plugins

这一节我想聊聊 ESLint 中 extendsplugins 这两个配置参数的区别,相信这会困扰很多人。

举个例子,假如我们要配置 ESLint x TypeScript,可以看到官网有这样的配置:

module.exports = {
  root: true,
  parser: '@typescript-eslint/parser',
  plugins: [
    '@typescript-eslint',
  ],
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended',
  ],
};
1
2
3
4
5
6
7
8
9
10
11

神奇的是,当你去掉 plugins 之后发现 eslint 依然可以正常工作。更神奇的是,只要你写了 extends,那么连 parser 也可以不用加,要知道没有指定 parser 选项,eslint 可看不懂你的 TypeScript 文件。

所以说,到底是 plugins 加上了 TypeScript 的能力还是 extends 加上了 TypeScript 的规则呢?真让人头大,直到终于有一天受不了了,翻找了一下网上的资料发现了这个帖子 (opens new window)

先来说结论吧:plugins 只是开启了这个插件,而 extends 则会继承别人写好的一份 .eslintrc 的配置,这份配置不仅仅包括了 rules 还有 parserplugins 之类的东西。

所以回到问题,为什么在继承了 plugin:@typescript-eslint/recommended 之后就可以不写 pluginsparser 呢?因为别人已经把配置都放在 recommended 这份配置表里了,这样对使用的人来说,就可以少写很多配置项了。

也就是说,下面两份配置是等价的:

module.exports = {
  parser: "@typescript-eslint/parser",
  parserOptions: { sourceType: "module" },
  plugins: ["@typescript-eslint"],
  extends: [],
  rules: {
    "@typescript-eslint/explicit-function-return-type": [
      "error",
      {
        allowExpressions: true
      }
    ]
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

以及

module.exports = {
  plugins: [],
  extends: ["plugin:@typescript-eslint/recommended"],
  rules: {
    "@typescript-eslint/explicit-function-return-type": [
      "error",
      {
        allowExpressions: true
      }
    ]
  }
}
1
2
3
4
5
6
7
8
9
10
11
12

对于第一份配置:

  • 需要手动添加 parser, parserOptions, plugins
  • 只开启了 @typescript-eslint/explicit-function-return-type 一个规则

对于第二份配置:

  • plugin:@typescript-eslint/recommended 自动添加了 parser, parserOptions, plugins
  • 自动加上一些推荐的 TypeScript 的 ESLint 规则
  • 自定义了 @typescript-eslint/explicit-function-return-type 规则

# 总结

看完这一章,我们了解到不仅写测试能提高代码信心,静态代码检查工具也可以给我们很强的代码自信。 具体的途径是配置 TypeScript 和 ESLint。

ESLint 中包含了两类规范:

  • 代码风格规范
  • 代码质量规范

Prettier 可以给我们提供一份相对全面的代码风格规范。建议把它与 ESLint 结合起来使用。

对于代码质量规范,开发者需要自己去找对应的框架提供的 ESLint 规范,比如有 Vue、React、Jest、React Testing Library 等。

最后顺带解释了 extendsplugins 两个配置项的区别:plugins 只是开启了这个插件,而 extends 则会继承别人写好的一份 .eslintrc 的配置, 这份配置不仅仅包括了 rules 还有 parserplugins 之类的配置项。

最后更新: 5/23/2022, 10:10:42 PM