准备工作

  1. 使用 vscode 新建一个项目(比如叫 my-project)
  2. 初始化 git 仓库(git init)
  3. 初始化 package.json ( npm init -y)
  4. 新建 src/main.js

项目结构如图
在这里插入图片描述

.git 目录没有出现在 vscode 编辑器中是正常的。

1. husky

在介绍 husky 之前,首先要理解什么是 hook(钩子),在前端 Vue 框架中提供了 beforCreated、created、beforeMounted、mounted 等函数、这些函数都是钩子,也常被称为‘生命周期钩子函数’,它们会在 Vue 实例化过程中有序地执行。

在 Git 中也存在一些钩子,其中较常用的有 pre-push、pre-commit ,其中 pre-commit 钩子会在 commit 前触发,pre-push 会在 push 前触发。(提示:所有钩子默认情况下是禁用的)

这些钩子可以用来干嘛?

比方我们可以利用pre-commit 钩子在 commit 时对代码先进行 eslint 检查,如果不合格就不给 commit,
不过使用 git 钩子稍微麻烦,于是就有了 husky ,它能让我们使用 git 钩子变得更加容易。

小插曲:关于“钩子”于”中间件“有什么区别,本人觉得没有区别,我甚至觉得钩子就是中间件,
因为无论是从作用、概念、实现上都能够作出合理的解释,如果你有更好的说法欢迎提出。

1.1 安装

npm i husky -D
npx husky install
npx husky add .husky/pre-commit

以上命令将会下载初始化 husky 并新增 pre-commit 钩子文件
在这里插入图片描述
下面只需在 pre-commit 文件自定义命令,即可在 commit 前触发,就这样,是不是很简单?

1.2 使用

pre-commit 内容如下

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

echo "Hello,world"

下面 commit 时将会提前输出 ‘Hello,world’,如图

在这里插入图片描述

可以在根目录新增 .gitignore 文件让 git 忽略掉不需要提交的文件,避免影响学习测试。

2. prettier

prettier 工具可以在代码保存时进行格式化与检查(检查比较少用,不过剧情需要,这里还是演示一下)
我们可以在 commit 前让 pre-commit 执行 prettier 来检查代码格式是否合格,合格了才给 commit。

2.1 安装

npm i prettier -D

2.2 配置

2.2.1 在项目根目录新建 .prettierrc 配置文件,内容如下:

{
    "tabWidth": 4, // 保存时为 4 个空格并以 tab 格式
    "singleQuote": true, // 保存时为单引号
}

关于 .prettierrc 更多配置可参考官方文档,这里仅作为演示。

2.2.2 在 pakcage.json 新增脚本命令

"scripts": {
	...
    "prettier:check": "prettier --config .prettierrc --check \"src/**/*.{js,ts,css,html}\"",
 	...
 },

2.2.3 在 husky/pre-commit 文件中将 echo “Hello,world” 修改为 npm run prettier:check

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm run prettier:check

2.3 使用

还记得 src/main.js 吗?现在我们对它修改如下:

function foo() {
console.log('Hello,foo') // 这里故意不缩进
}

效果如图

在这里插入图片描述
当然我们也可以让 prettier 除了检查外还能自动修复,这里用到 prettier 提供的另一个选项 --write

"scripts": {
	...
    "prettier:check": "prettier --config .prettierrc --check \"src/**/*.{js,ts,css,html}\" --write",
 	...
 },

效果如图

在这里插入图片描述
可以看到 commit 提交成功,代码也自动帮我们格式化,如图:

function foo() {
    console.log('Hello,foo'); // 多了 4 个空格
}

注意,虽然格式化了,但 main.js 文件状态并没有一起 commit 上去,仍然处于修改状态,如图:

在这里插入图片描述
也就是说 prettier 修复后,我们还要手动再次 git add . & git commit 上去,很明显,这不是我们想要的效果,这样只会增加无用的 commit 提交记录,为了解决这个问题,只需在 pre-commit 钩子新增以下命令即可

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# 新增 git add -A .
npm run prettier:check && git add -A .

现在我们重新对 main.js 进行格式错乱并 commit 提交,效果如图

在这里插入图片描述
一切正常

prettier 检查代码只是它的一部分,上面仅仅是配合 husky 作为演示,它更多的是用来代码保存自动格式化,怎么配置保存自动格式化网上有很多例子,这里不在讲述。

3. eslint

eslint 可以对代码进行约束规范,如果代码不符合规范则会在下面呈现一条~~~~ 红色的波浪线,
相比于 prettier 的检查,eslint 更丰富更强大,因此 prettier 常用于保存自动格式化代码, 而 eslint 作为代码规范检查,两者可以结合使用。

3.1 安装

npm i eslint -D

3.2 配置

3.2.1 在根目录新建 .eslintrc.js 配置文件,内容如下

// eslint-disable-next-line no-undef
module.exports = {
    "env": {
        "browser": true,
        "es2021": true
    },
    "extends": "eslint:recommended",
    "parserOptions": {
        "ecmaVersion": "latest",
        "sourceType": "module"
    },
    "rules": {
    }
}

关于 .eslintrc.js 更多配置可参考官方文档,这里仅作为演示。

3.3 效果

在这里插入图片描述
可以看到 main.js 出现了红色波浪线,因为 foo 未被任何地方引用。

3.4 结合 husky

3.4.1 在 package.json 新增脚本

"scripts": {
   	...
    "eslint:check": "eslint src/*.js"
    ...
  },

3.4.2 在 pre-commit 新增脚本

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
# 注释
# npm run prettier:check && git add -A .
# 新增
npm run eslint:check

3.4.3 效果如图

在这里插入图片描述
可以看到 eslint 检测到 main.js 不符合规范并抛出错误,导致 commit 提交失败,
现在我们想让 eslint 自动修复这些报错只需在 packages.json 脚本中新增 --fix 选项即可

"scripts": {
	...
	"eslint:check": "eslint src/*.js --fix"
	...
}

现在继续 commit ,你会看到问题依旧存在

在这里插入图片描述
难道 --fix 选项不生效?其实是生效的,只是 eslint 只会自动修复 .eslintrc.js 里对应的 rules,其它的只能手动修复,像上面未引用的这种类型错误只能自己去处理,不信我们来验证一下:

首先在 .eslintrc.js 里面新增一条规则

// eslint-disable-next-line no-undef
module.exports = {
   	....
    "rules": {
        "comma-spacing": ["error", { "before": false, "after": true }],
    }
}

该规则表示逗号之间必须要有空格,否则就会出现波浪线,如图

在这里插入图片描述

现在我们再次 commit

在这里插入图片描述

虽然 commit 提交失败,但可以看到 eslint 已经自动修复了逗号之间没有空格的问题,
剩下的只需手动把未引用的错误手动解决即可。

4. lint-staged

上面的插件都需要指定文件才能进行检查,比如 eslint 命令需要指定 src/*.js ,但这样会产生新的问题,如果 src 目录存在着大量的 .js 文件,那么每次执行 eslint 时都会对所有文件检查&修复,很明显除了对性能有影响外,还会影响同事以前写过的代码格式。

有没有办法能让这些工具只检查&修复我们修改过的文件就好呢? lint-staged 就可以做到。
lint-staged 能让这些插件只扫描暂存区的文件而不是全盘扫描,很明显,这就是我们想要的工具。

4.1 安装

npm i lint-staged -D

4.2 配置

4.2.1 在 package.json 新增 lint-staged 选项

  "scripts": {
    ...
  },
  "lint-staged": {
    "src/**/*.{js,jsx,ts,tsx,json,css,scss,md}": [
      "eslint --fix"
    ]
  },

4.2.2 在 pre-commit 新增命令

```sh
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
# 注释
# npm run prettier:check && git add -A .
# 注释
# npm run eslint:check
# 新增
npx lint-staged

4.3 使用

现在假设 src 目录有一个 foo.js 文件,里面代码格式是错乱的

在这里插入图片描述

为了验证 lint-staged 会忽略掉除暂存区以外的文件,我们把这个 foo.js 先提交到本地仓库,
这里可以使用 git commit -m'test' -n 其中 -n 表示忽略 pre-commit 钩子,直接提交上去。

上面铺垫好了,下面开始验证 main.js ,代码格式如图

在这里插入图片描述
接下来 commit,效果如图
在这里插入图片描述
上面呈现一大串的东西不用担心,说明 lint-staged 正常运行,我们来看看 main.js 文件有没有发生变化,如图

在这里插入图片描述
可以看到 main.js 的逗号被修复并成功 commit 提交上去 ,且 foo.js 也不会受到影响,如图:

在这里插入图片描述

案例代码已上传到 github

完!

参考文献
https://github.com/typicode/husky/issues/949
https://medium.com/@anshul.kashyap03/set-up-git-hooks-with-husky-and-lint-staged-angular-example-a4d46e440ba5
https://laurieontech.com/posts/husky/
https://www.npmjs.com/package/husky

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐