各位靓仔靓女们,晚上好!我是你们的老朋友,今晚咱们来聊聊 JavaScript 界的“二哈”—— Husky。
别误会,此“二哈”非彼“二哈”,它可不是那种拆家捣蛋的宠物,而是 Git Hook 的好帮手,能让你的代码提交变得更加规范和可靠。简单来说,它就像一个尽职尽责的门卫,帮你把控代码质量的最后一道关卡。
一、Husky 是个啥?为什么要用它?
首先,我们得明白 Git Hook 是什么。Git Hook 就像 Git 的钩子函数,在特定的 Git 事件发生时(例如 commit、push 等),会自动触发你预先设定的脚本。
但是,手动配置和管理 Git Hook 非常麻烦,容易出错,而且需要对每个开发者都进行设置。这时候,Husky 就闪亮登场了。
Husky 就像一个 Git Hook 管理器,它能:
- 简化
Git Hook的配置: 用简单的npm命令就能安装和配置,无需手动修改.git/hooks目录。 - 项目级别配置:
Husky的配置保存在package.json文件中,跟随项目一起版本控制,保证团队成员使用相同的Hook设置。 - 支持各种脚本语言: 你可以使用
JavaScript、Shell、Python等任何你喜欢的脚本语言来编写Hook脚本。 - 提高代码质量: 通过
Hook脚本,你可以自动化地执行代码检查、单元测试、代码格式化等操作,从而避免低级错误和风格不一致的代码被提交。
举个例子,你可能希望在每次提交代码前,都自动运行 ESLint 来检查代码风格,或者运行 Jest 来进行单元测试。有了 Husky,这些都能轻松实现。
二、如何安装和配置 Husky?
-
安装
Husky:首先,确保你的项目已经初始化了
npm或yarn。 然后,在你的项目根目录下运行以下命令:npm install husky --save-dev # 或者 yarn add husky --dev -
启用
Git Hook:安装完成后,你需要启用
Git Hook。运行以下命令:npx husky install # 或者 yarn husky install这会在你的项目根目录下创建一个
.husky文件夹,用于存放Hook脚本。 -
添加
Hook脚本:现在,你可以添加你想要的
Hook脚本了。Husky支持的Hook类型有很多,常用的包括:pre-commit:在commit之前运行。commit-msg:在commit消息编辑后运行。pre-push:在push之前运行。prepare-commit-msg: 在commitmessage 准备阶段运行
例如,如果你想在每次
commit之前运行ESLint检查代码风格,可以这样做:npx husky add .husky/pre-commit "npm run lint" # 或者 yarn husky add .husky/pre-commit "yarn lint"这个命令会在
.husky/pre-commit文件中创建一个脚本,内容是npm run lint或yarn lint。 假设你的package.json文件中有如下配置:{ "scripts": { "lint": "eslint . --ext .js,.jsx,.ts,.tsx" } }那么,每次你运行
git commit命令时,Husky都会自动执行eslint . --ext .js,.jsx,.ts,.tsx命令来检查你的代码风格。 如果ESLint发现了任何错误,commit就会被阻止,直到你修复了错误为止。 -
简化配置方式(
Husky v6+):Husky v6引入了一种更简洁的配置方式,直接在package.json文件中配置Hook。 首先,在package.json中添加husky配置:{ "husky": { "hooks": { "pre-commit": "lint-staged" } }, "scripts": { "lint": "eslint . --ext .js,.jsx,.ts,.tsx", "format": "prettier --write ." }, "devDependencies": { "husky": "^6.0.0", "lint-staged": "^10.0.0", "eslint": "^7.0.0", "prettier": "^2.0.0" } }然后,运行
npm install或yarn install安装依赖。这种方式更加清晰明了,方便管理和维护。
三、Husky + lint-staged:黄金搭档
通常,我们不会对所有文件都进行代码检查和格式化,而是只关注那些被修改的文件。 这时候,lint-staged 就派上用场了。
lint-staged 是一个只对 Git 暂存区(stage)中的文件执行 lint 命令的工具。 它可以显著提高 lint 的速度,避免对未修改的文件进行不必要的检查。
-
安装
lint-staged:npm install lint-staged --save-dev # 或者 yarn add lint-staged --dev -
配置
lint-staged:在
package.json文件中添加lint-staged配置:{ "lint-staged": { "*.{js,jsx,ts,tsx}": [ "eslint --fix", "prettier --write", "git add" ] } }这个配置表示,对所有
.js、.jsx、.ts、.tsx文件,先运行eslint --fix来自动修复代码风格问题,然后运行prettier --write来格式化代码,最后运行git add将修改后的文件重新添加到暂存区。 -
将
lint-staged集成到Husky中:修改
husky配置,将pre-commit钩子指向lint-staged:{ "husky": { "hooks": { "pre-commit": "lint-staged" } } }现在,每次你运行
git commit命令时,Husky都会自动执行lint-staged,只对暂存区中的文件进行代码检查和格式化。
四、一些进阶用法和注意事项
-
跳过
Hook:有时候,你可能需要临时跳过
Hook,例如当你需要提交一些未完成的代码时。 你可以使用git commit --no-verify或git push --no-verify命令来跳过Hook。 -
自定义
Hook脚本:你可以编写自己的
Hook脚本来实现更复杂的功能。 例如,你可以编写一个Hook脚本来检查commit消息的格式,或者检查代码中是否包含敏感信息。举个例子,我们可以编写一个
commit-msg钩子来检查commit消息是否符合规范:#!/bin/sh COMMIT_MSG_FILE=$1 COMMIT_MSG=$(cat $COMMIT_MSG_FILE) # 检查 commit 消息是否以 "feat:", "fix:", "docs:", "style:", "refactor:", "test:", "chore:" 开头 if ! echo "$COMMIT_MSG" | grep -E "^(feat|fix|docs|style|refactor|test|chore)(([a-z]+))?:s.+"; then echo "Error: Commit message must start with feat:, fix:, docs:, style:, refactor:, test:, or chore: followed by a description." exit 1 fi exit 0然后,将这个脚本添加到
.husky/commit-msg文件中,并赋予执行权限:chmod +x .husky/commit-msg现在,每次你提交代码时,
Husky都会自动运行这个脚本来检查commit消息的格式。 -
处理
Hook失败:默认情况下,如果
Hook脚本执行失败,commit或push操作会被阻止。 你可以使用husky.allowEmpty配置来允许空的commit,即使Hook失败。{ "husky": { "hooks": { "pre-commit": "lint-staged", "commit-msg": "your-commit-msg-script" }, "allowEmpty": true } }但通常不推荐这样做,因为这会降低代码质量的保证。
-
与 CI/CD 集成:
Husky也可以与 CI/CD 工具集成,例如 Jenkins、Travis CI、GitHub Actions 等。 这样,你可以在每次构建或部署时,都自动运行Hook脚本来检查代码质量。
五、一个完整的例子
假设我们有一个 React 项目,使用 ESLint、Prettier 和 Jest 来进行代码检查、格式化和单元测试。 我们可以这样配置 Husky:
-
安装依赖:
npm install husky lint-staged eslint prettier jest --save-dev # 或者 yarn add husky lint-staged eslint prettier jest --dev -
配置
package.json:{ "scripts": { "lint": "eslint . --ext .js,.jsx,.ts,.tsx", "format": "prettier --write .", "test": "jest", "prepare": "husky install" }, "husky": { "hooks": { "pre-commit": "lint-staged" } }, "lint-staged": { "*.{js,jsx,ts,tsx}": [ "eslint --fix", "prettier --write", "jest --findRelatedTests", "git add" ] }, "devDependencies": { "eslint": "^7.0.0", "prettier": "^2.0.0", "jest": "^26.0.0", "husky": "^6.0.0", "lint-staged": "^10.0.0" } }注意:
prepare脚本会在npm install或yarn install之后自动运行husky install,这样可以确保在安装依赖后,Husky能够正确地启用Git Hook。 -
初始化
ESLint和Prettier:运行以下命令来初始化
ESLint和Prettier:npx eslint --init npx prettier --write .根据提示选择合适的配置。
-
编写单元测试:
编写一些单元测试来测试你的代码。
现在,每次你运行 git commit 命令时,Husky 都会自动执行以下操作:
- 只对暂存区中的
.js、.jsx、.ts、.tsx文件进行代码检查和格式化。 - 运行
Jest来测试与这些文件相关的单元测试。 - 如果一切顺利,
commit就会成功。 否则,commit会被阻止,直到你修复了错误为止。
六、Husky 的优点和缺点
| 优点 | 缺点 |
|---|---|
| 提高代码质量 | 如果 Hook 脚本执行时间过长,会影响开发效率。 |
| 自动化代码检查和格式化 | 需要配置和维护 Hook 脚本。 |
| 强制团队成员遵循相同的代码风格 | 有些开发者可能不喜欢强制性的代码检查和格式化。 |
简化 Git Hook 的配置和管理 |
如果 Hook 脚本编写不当,可能会导致意外的错误。 |
| 可以与 CI/CD 工具集成,实现自动化代码质量控制 | 在某些情况下,Husky 可能会与其他的 Git Hook 工具冲突。 |
七、总结
Husky 是一个非常实用的 Git Hook 管理工具,可以帮助你提高代码质量、自动化代码检查和格式化,并强制团队成员遵循相同的代码风格。 配合 lint-staged 使用,可以显著提高 lint 的速度。
虽然 Husky 也有一些缺点,但总体来说,它的优点远大于缺点。 如果你还没有使用 Husky,强烈建议你尝试一下,相信它会给你的开发工作带来很大的帮助。
好了,今天的讲座就到这里。 希望大家都能成为代码界的“猛男”和“靓女”,写出高质量的代码! 感谢大家的聆听! 记得点赞收藏加关注哦! 下次再见!