大厂都在用的代码规范与代码检测工作流

10,152 阅读7分钟

关注+点赞,好人一生平安

我正在参加「掘金·启航计划」。

前言

一般来说,团队协作中最让人抓狂的就是代码规范,同时这也是最容易妥协的地方。所以好的代码规范能让团队减少很多无谓的“争吵”和时间的浪费。

下面介绍一下,大厂都在用的代码规范与代码检测工作流。

代码规范

eslint + prettier

代码检测工作流

husky + lint-staged

代码规范

lint工具最早可追寻到1979年,它的作用是用于扫描C源文件并对程序中不可移植的代码发出警告。因为在C语言发展初期,由于程序员的风格问题,导致在移植代码时会出现一些不严谨的代码片段导致无法被编译器执行的问题。1979年贝尔实验室开发了一个静态代码分析的工具,并将其命名为lint,所以后续的类似的代码检测工具都延续该命名风格,比如ESLint、JSLint等。

在JavaScript诞生至今的20多年的时间里,出现过许许多多的lint工具,其中最主流的是以下三种:

  • JSLint
  • JSHint
  • ESLint

JSLint

JSLint是由著名的JavaScript布道者Douglas Crockford发明的。他在他著作《JavaScript语言精粹》中列举出JavaScript糟粕和鸡肋的属性,为了不让开发者继续用这些属性,他开发了JSLint工具,并在2010年进行开源。Douglas在JSLint中禁止使用JS中的所有的糟粕属性并且不可配置,所以使用JSLint,就相当于必须接受他的所有规则。

JSHint

JSLint面世后,虽然确实能帮助许多开发者,但是问题也有不少,其中最要命的是:

  • 没有提供代码风格和规则的配置(被JSHint的作者吐槽使用JSLint只是让开发者的代码风格更像Douglas而已)

于是JSHint在JSLint的基础上增加了可配置的规则,由此让JSHint迅速取代了JSLint(当然不止这个功能,但这个功能是最核心的)。

ESLint

ESLint最初是由Nicholas C. Zakas(红宝书的作者)于2013年6月创建的开源项目。它的目标是提供一个插件化的JavaScript代码检测工具。ESLint与JSHint不同,它是采用将源代码解析成AST,然后检测AST来判断代码是否符合规范。这个特性使得它能够在ES6刚出现的时候,成为最快支持ES6语法的lint工具:因为只需有合适的解析器就能够进行Lint检测(比如babel-eslint),从此ESLint就快速取代JSHint成为了老大。

ESLint使用espress将JavaScript代码解析成AST,然后通过AST来分析代码,从而给代码两种提示:

  • 代码质量问题
  • 代码风格问题

ESLint主要解决的其实是代码质量问题,因为代码质量出问题那就意味着有很大几率会出现BUG。

1、安装依赖

npm install -D eslint

2、初始化eslint配置,通过经典的一问一答环节来帮助用户快速地创建.eslintrc文件

npx eslint --init

3、然后就可以在任何文件或目录上运行ESlint

npx eslint yourfile.js

4、检测出问题后,可以使用--fix来自动修复代码

npx eslint --fix yourfile.js

Airbnb

对于代码风格问题,业界有几个比较出名的规范,其中Airbnb公司的规范最为人推崇。
1、安装依赖

npm install -D eslint-config-airbnb

2、在.eslintrc文件设置如下:

{
    "extends": ["airbnb"]
}

Prettier

ESLint+Airbnb就完美了吗?那是不可能的,如上所说,ESLint主要是解决代码质量问题,对于代码风格问题并没有太多的约束,而且就算是Airbnb也并不是覆盖方方面面的风格,而且也不是所有人都能接受的。

这时候出现了一个名为Prettier的代码格式化工具,它是opinionated的。采用Prettier的最大原因是为了停止所有关于代码风格的争论,它认为使用哪种代码风格不重要,重要的是用没用。所以Prettier提倡先提高代码的可读性和可维护性,至于具体使用什么风格它给我们定,这也是opinionated的意义。

Prettier原理非常简单,它不管你写的代码是什么样子的,它会去掉代码里的所有样式风格,然后用统一固定的格式重新输出。它通常是考虑行长(line length)来获取代码并重新输出。

比如说:

foo(arg1, arg2, arg3, arg4);

一行能装得下,那就不需要修改。

如果是这样:

foo(reallyLongArg(), omgSoManyParameters(),IShouldRefactorThis(), isThereSeriouslyAnotherOne());

那就太长了,Prettier就会进行规范:

foo(
  reallyLongArg(),
  omgSoManyParameters(),
  IShouldRefactorThis(),
  isThereSeriouslyAnotherOne()
);

原理也是将代码转换为AST,然后再这个AST上重新按照自己的风格输出代码。

1、安装依赖

npm install --save-dev --save-exact prettier

2、创建一个空的配置文件,让编辑器知道正在使用Prettier(Prettier只有少许的配置项)

echo {}> .prettierrc.json

3、现在就可以使用Prettier规范所有文件

npx prettier --write

与ESLint结合

ESLint+Prettier就能完美的解决代码质量和代码风格的问题。但是ESLint本身也有代码风格的解决方法,所以与Prettier配合起来就有点麻烦。

1、安装依赖

npm install -D eslint-config-prettier eslint-plugin-prettier

2、配置.eslintrc文件

// .eslintrc
{
  "extends": ["plugin:prettier/recommended"]
}

这个配置包含两个内容:

  • 使用eslint-config-prettier来关掉eslint中所有与prettier冲突的配置。
  • 使用eslint-plugin-prettier将prettier的rules以插件的形式加入到ESlint里面。

配置vscode

源码检测完全依赖开发者手动运行eslint命令来完成,这是反人类的做法。有一个方法可以在开发过程中能做代码检测,那就是与编辑器结合。

以vscode编辑器为例,需要安装ESLint拓展插件。该插件会读取当前项目中.eslintrc的配置,并在编辑器中提示不符合规范的代码。

vscode的ESLint插件也能设置自动修复,只需打开ESLint插件的Auto Fix On Save配置即可。这样每次保存文件时,就能自动进行修复。

代码检测流程

配置vscode进行检测属于个人行为,有些人不但没有配置编辑器,而且提交代码前也没有手动运行eslint来检测代码。这如果把没进行过eslint检测的代码提交上去远程的git仓库,那就可能造成大的影响。

这时候就要借助husky。

husky

husky可以增强commit,可以使用它来检测commit message、run test或者lint code等。husky支持所有的git hooks。

1、安装husky

npm install -D husky

2、开启Git hooks

npx husky install

husky install命令会创建.husky/目录并指定该目录为git hooks所在的目录。

3、在package.json中添加prepare脚本

{
    "scritpts": {
        "prepare": "husky install"
    }
}

prepare脚本会在npm install之后自动执行。

4、添加git hooks,运行以下命令创建git hooks

npx husky add .husky/pre-commit "eslint --fix"

运行完该命令后,.husky/目录下会新增一个名为pre-commit的shell脚本,该脚本内容如下:

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
   
eslint --fix

该脚本的功能就是执行eslint --fix命令。

最后尝试git提交:

git commit -m 'Keep calm and commit'

就会执行eslint --fix命令检测代码。

lint-staged

其实这种做法并不明智,因为可能我只提交A文件,那么所有的文件都要经过eslint的扫描。

所以理想的做法是只检测本次提交的文件,lint-staged就是基于这种想法而开发的。lint-staged中staged指的是git的提交区。

1、安装lint-staged

npm install -D lint-staged

2、然后修改package.json配置

{
    "scripts": {
        "lint": "lint-staged",
    },
    "lint-staged": {
        ".{js}": [
            "eslint --fix",
            "prettier --write"
        ]
    }
}

3、修改.husky/pre-commit配置

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
   
npm run lint

4、最后尝试git提交:

git add A.js
git commit -m 'Keep calm and commit'

就会执行npm run lint命令检测已在提交区的代码。

最后

如果本文对你有帮助,就点个赞支持下吧,你的「赞」是我持续进行创作的动力。

楼主github, 如果喜欢请点一下star,对作者也是一种鼓励。