基于 git hooks 的前端代码质量控制解决方案

@一棵菜菜  September 2, 2019

一、为什么需要在git hook里配置预处理 ?

现在确保代码规范及质量,已经有很多的Lint工具,如Eslint,styleLint等。大家在开发过程中会自觉运行这些工具,然后根据工具给出的提示信息进行修复或修改代码。但是,有时候大家一粗心可能就漏看了(或者根本没看。。)这些提示、忘记了部分规范要求而直接把代码提交的情况!!

既然这种靠自觉是靠不住的,那我们只能让整个流程自动化、让工具替我们完成代码规范检查的事情。

所以理想的方式是:
我们在git hooks里配置各种预处理脚本,比如代码检查或者跑单元测试之类的事情,如果我们的代码没有通过代码检查或者测试用例覆盖率不够,我们的commit或者push会直接被拒绝。

具备基本工程素养的同学都会注重编码规范,而代码风格检查(Code Linting,简称 Lint)是保障代码规范一致性的重要手段。

二、什么是git hooks?

钩子(hooks)是一些在"$GIT-DIR/hooks"目录的脚本, 在被特定的事件(certain points)触发后被调用。当"git init"命令被调用后, 一些非常有用的示例钩子文件(hooks)被拷到新仓库的hooks目录中; 但是在默认情况下这些钩子(hooks)是不生效的。 把这些钩子文件(hooks)的".sample"文件名后缀去掉就可以使它们生效了。

也就是在我们的git仓库下会有一个.git配置文件夹,它里面包含git操作相关的一系列 预处理/后处理 脚本。如 pre-commitpost-push之类的。


三、Lint 是什么?

简单来说,Lint 就是对代码做静态分析,并试图找出潜在问题的工具,实战中我们也用 Lint 来指使用工具的过程,如Eslint,styleLint等。


四、提交后 Lint:反馈链条太长

很多同学选择在持续集成阶段(通过持续集成工具(CI)对每次提交的代码做)做 Lint,比如使用远程的 Git Hooks 来触发。依靠CI(持续集成工具)对每次提交的代码做code check,每次接收push之前跑一下code check,如果没有通过直接拒绝接收push。
但是从实际的经历来看,这种做法的反馈链条通常如下:

代码提交 --> 发现问题(远程) --> 修复问题 --> 重新提交 --> 通过检查(远程)

整个过程可能会浪费掉你不少时间,毕竟 CI 过程通常不仅是在做 Lint,如果你是那种不知道自己时间每天都去哪儿了的工程师,可以反思下自己或者团队的工作流是否是这样。并且,请相信我,你不是少数人。

五、提交前 Lint【常用】

为了缩短 Lint 的反馈链条,把 Lint 挪到本地是最有效的办法。常见做法是使用 husky 或者 pre-commit 在本地提交之前做 Lint。

1. 使用插件husky

查看github:husky

Husky can prevent bad git commit, git push and more woof!

效果:配置了pre-commit之后每次代码提交之前 git都会自动去跑我们配置的代码检查及单元测试任务,都跑通过之后才能提交成功。

下载

npm install husky --save-dev

然后修改 package.json,增加配置:

{
  "husky": {
    "hooks": {
      "pre-commit": "eslint src/**/*.js"
    }
  }
}

最后尝试 Git 提交,你就会很快收到反馈:

git commit -m "Keep calm and commit"
husky插件实现的机制大致是,在你install该插件时,它会自动往git hooks里埋入很多相应的钩子脚本(git hook能识别的),这些钩子函数会去读区package.json中的配置信息,当用户做某些git操作触发相应钩子时会自然去调用配置好的任务,从而实现我们的自动化需求,包括代码检查跟单元测试验证以及更多的自动化任务。

2. 每次提交只检查本次提交所修改的文件:husky+lint-staged【常用】

查看github:lint-staged

把 Lint 挪到本地,并且每次提交只检查本次提交所修改的文件是 常用的做法。

lint-staged:针对暂存的git文件运行linters并且不要让bug进入你的代码库。

为什么需要lint-staged?

在提交代码之前,Linting在运行时更有意义。通过这样做,您可以确保没有错误进入存储库并强制执行代码样式。但是对 整个项目 运行一个lint进程很慢,而且linting结果可能无关紧要。最终,您只想要提交 将要提交的lint文件,所以可以使用lint-staged

下载

npm install husky --save-dev
npx install lint-staged --save-dev

使用

// 根目录package.json
{
  ...
 "scripts": {
    "bundle": "webpack",
    "watch": "webpack --watch",
    "start": "webpack-dev-server",
    "test": "mocha -t 10000"
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "test/**/(*.test).js": "npm test",
    "src/**/*.js": [
      "eslint --fix",  // lint-staged 给了你提交前代码操作的更大自由度,比如这里的自动修复js错误
      ""prettier --write", // 自动格式化代码(prettier插件)
      "git add"
    ]
  }
}

此外,lint-stagedprettier 已经集成到 create-react-app 中了。你是不是也应该好好打磨下自己的 Lint 工作流了?

查看github:husky
查看github:lint-staged

部分摘抄自《基于 git hooks 的前端代码质量控制解决方案》
部分摘抄自《用 husky 和 lint-staged 构建超溜的代码检查工作流》


添加新评论