从代码规范说起

由于我们每个人对 JavaScript 的理解不同,编写代码的习惯也不同,所以在合作编写项目时,难免会出现代码风格的不同。这种差异性导致了团队协作的效率低下,也影响了项目的健壮性和可维护性。所以,我们需要对代码风格进行规范。这种规范不仅可以使代码风格保持统一,并且可以在代码运行之前就检测出一些错误和 Bug,提高协作开发效率。

lint 是最著名的 C 语言工具之一,作用是静态代码分析,它被用于检查 C 程序中潜在的错误,包括(但不限于)可疑的类型组合、未使用的变量、不可达的代码以及不可移植的代码等等。

而 ESLint 则是 2013 年推出的 JavaScript 的 lint 工具。命名前缀的来源是由于 JavaScript 也被称为 ECMAScript(ES)。

ESLint 是在 ECMAScript/JavaScript 代码中识别和报告模式匹配的工具,它的目标是保证代码的一致性和避免错误。

ESLint 可以在运行代码前就发现一些语法错误和潜在的 Bug,极大地减轻测试人员的压力,减少软件项目的除错成本。同时,ESLint 允许开发者通过 rules 定义自己的代码规范,所以非常适合用于制定团队代码规范。

引入

  • 引入 ESLint:注意只需要将依赖安装到开发环境
npm install eslint --save-dev

# or

yarn add eslint --dev

然后我们输入 npm init @eslint/configyarn create @eslint/config 回答问题进行配置。

image-20220217215148544

之后再使用 yarn install 进行依赖补全。

什么是 airbnb?且听下节分解。

常见的标准规范

我们在 eslintrc.js 中以 CommonJS 格式规定我们的标准规范。

module.exports = {
  env: {
    browser: true,
    es2021: true,
  },
  extends: [
    'plugin:react/recommended',
    'airbnb',
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
    },
    ecmaVersion: 'latest',
    sourceType: 'module',
  },
  plugins: [
    'react',
    '@typescript-eslint',
  ],
  rules: {
  },
};

eslint:standard

standard 是基于 recommended 衍生出来的更严格的规范。其与后者的不同之处主要是 recommended 很多都是 off, standard 是 error, 比如 单行代码块两边加空格禁止使用分号结尾

先使用 npm i standard eslint-plugin-standard eslint-config-standard -D 命令安装 standard 插件,然后在 eslintrc.js 文件中写入以下内容后,将会启用 standard 规范:

module.exports = {
  root: true,
  extends: ['standard']
};

standard 会比 recommended 更加严格,在代码风格上也做了一些限制。不过它的用户群体也是比较多的,也不乏一些大家耳熟能详的。

image

Airbnb

Airbnb 规范是最严格的 ESLint 规范,列出下面几点比较明显的区别:

  1. 默认必须要分号,而 ESLint 默认不添加分号
  2. 不能使用 for 循环,推荐使用数组自带的 API 完成遍历工作。
  3. 当你必须使用函数表达式(或传递一个匿名函数)时,使用箭头函数符号。

除了这些以外,还有更多严格的规则,可以参考:

  • 补充:Babel-eslint ?

https://www.npmjs.com/package/@babel/eslint-parser

ESLint’s default parser and core rules only support the latest final ECMAScript standard and do not support experimental (such as new features) and non-standard (such as Flow or TypeScript types) syntax provided by Babel. @babel/eslint-parser is a parser that allows ESLint to run on source code that is transformed by Babel.

Note: You only need to use @babel/eslint-parser if you are using Babel to transform your code. If this is not the case, please use the relevant parser for your chosen flavor of ECMAScript (note that the default parser supports all non-experimental syntax as well as JSX).

TypeScript

直接说结论,使用以下插件:

  • @typescript-eslint/parser
  • @typescript-eslint/eslint-plugin

在上述回答问题的过程中会帮我们自动补全在 package.json 中。

对照:Prettier

  • 什么是 Prettier

Prettier 在自己官网首页列出这么三点:

  • An opinionated code formatter
  • Supports many languages
  • Integrates with most editors
  • Has few options

官方首先告诉你,Prettier 是一个 Opinionated 的代码格式化工具。所以要掌握 Prettier 的精髓就是要理解这个单词。

对比 Angular, ExpressJS 和 SpringBoot 的 Unopinionated,Prettier 说自己是一个 Opinionated code formatter,就是说:你必须认同我的观点,按照我说的做。否则你就别用我,硬着头皮用就会处处不爽!

Has few options,其实就是 Opinionated 的最直接体现。除了必要的设置项,不会再给你们更多。给你设置项越多,你们越乱,你们就会继续争吵!

Prettier 的原理非常简单:

不管你写的代码是个什么鬼样子,Prettier 会去掉你代码里的所有样式风格,然后用统一固定的格式重新输出。输出时基本上只考虑一个参数,就是 line length。

而 Prettier 与 Linters 有什么区别呢?

  • Formatting rules

当 ESLint 遇到上面的 incorrect code 的时候,会提示你违反规则,让你修改代码以符合规则。

而 Prettier 则不会这么麻烦,它根本不管你之前符不符合什么规则,都先把你的代码解析成 AST,然后按照它自己的风格给你重新输出代码。

换句话说,Prettier 对应的是各种 Linters 的 Formatting rules 这一类规则。而且你用了 Prettier 之后,就不会再违反这类规则了!不需要你自己手动修改代码。

  • Code-quality rules

Prettier 对这类规则束手无策。而且这类规则也正是各种 Linters 的重点,因为它们真的能帮你发现很多低级的 Bug。

所以,Prettier 并不会取代各种 Linters,而是能避免你的代码和这些 Linters 定义的 Formatting rules 冲突。Linters 检查出来违反 Code-quality rules 的情况后还需要你自己根据业务逻辑和语法手动修改。Prettier 帮你格式化代码,但是不会帮你挑出潜在的错误。

那么既要让 Prettier 帮你格式化代码,还想让 Linters 帮你挑出潜在的 Code-quality 类错误,怎么办?就需要 Prettier 和 Linters 配合使用。

以上摘自:参考资料中的《Prettier》文

现在 ESLint 也有了 --fix 功能,暂且搁置一下 Prettier 的学习。

配置

// TODO

Git

husky

在项目开发过程中,自动格式化并不总是让人安心的,因为并不是项目组的所有成员都会使用插件来做自动格式化。

这样的情况会导致有一些不规范的代码被提交到服务端,依然会造成团队规范不一致的问题,这个时候就需要用到提交时自动检测和格式化代码的功能。

接下来,我们将使用 husky Hook 来进行代码提交时的自动检测工作。

先使用 npm i husky -D 安装依赖,在依赖完成完成后,我们需要使用下面这条命令初始化 husky

husky install
npx husky add .husky/pre-commit "npm pre-commit"

我们还需要在项目的 package.json 中,添加 pre-commit,这个命令运行时进行 eslint 检测(如下)。

"scripts": {
  "pre-commit": "eslint src"
}

lint-staged

如果我们希望在检测错误的同时,自动修复 eslint 语法错误,则需要用到 lint-staged,使用 npm i lint-staged -D 先进行安装,然后在 package.json 中修改 pre-commit 命令,再添加以下内容。

"scripts": {
  "pre-commit": "lint-staged"
},
"lint-staged": {
  "src/**": [
    "eslint --fix"
  ]
}

lint-staged Repo 地址:https://github.com/okonet/lint-staged

lint-staged 针对暂存的 git 文件运行 linters,不要让不符合规则的代码溜进代码库。lint-staged总是将 所有暂存文件的列表传递给任务,忽略任何文件都应该在任务本身中配置,比如:.prettierignore / .eslintignore 。lint-stage 总是配合 husky 一起使用。

Reference