Git 钩子是当今开发作业流程中最不可或缺的部分之一。钩子有助于在一个有多个贡献者的大型代码库中坚持代码质量。跟着提示、代码格式化和类型查看的引入,Git Hook的使命比以往更多。
关于前端开发者(或一般的JavaScipt开发者)来说,Husky是办理Git Hooks的首选。虽然Husky很受欢迎,但它缺少并行化,而并行化能够加速钩子的履行速度。它还向node_modules
,这可能是一个问题。
在这篇文章中,咱们将看看Lefthook,一个更快、更简略、更强壮的Husky替代品,适合前端开发者。咱们将经过把Lefthook增加到一个React和React Native运用的样本中,来看看Lefthook与Husky的比照状况。
什么是Lefthook?
基于JS的前端社区已经发展到用其他言语开发的东西现在支撑JS开发。Lefthook是这一趋势的产物;它运用Go开发,声称是Node.js和Ruby的最快的polyglot Git Hooks办理器,但我相信它对其他库房也很有用。由于它是经过单一的二进制文件作业的,所以node_modules
目录受到的污染较少。
杰出的特色
Lefthook在Git Hook办理器中脱颖而出,由于它有令人难以置信的功用,能够在没有任何办理麻烦的状况下加强开发作业流程。这儿列出的一切功用在Husky中都是不可用的。
平行履行
Lefthook是用Go开发的,这使它在运用机器的并行化方面有更大的潜力;完成使命的并行履行只是一个单行问题。
并行履行是大规模运用的最重要要求之一。关于较大的提交,人们能够运用拼写查看、类型查看、ESLint和StyleLint等并行方法,为开发者节省很多时刻。我将在后边共享一个React运用中的比方。
挑选要查看的文件
Lefthook帮忙在有限的文件集上履行指令,有预置的速记东西、glob和RegEx过滤器,以及在子目录中运转的选项。
假如你在预提交使命中运转JS linters和StyleLints,这可能是超级有用的;抱负状况下,类型查看使命将与完好的文件列表一起进行,而ESLint和StyleLint将被运用于分阶段文件。下面是挑选文件来履行使命的比方。
-
Glob
pre-commit: commands: lint: glob: "*.{js,ts,jsx,tsx}" run: yarn eslint
-
速记本
pre-commit: commands: frontend-linter: glob: "*.{js,ts,jsx,tsx}" # glob filter for list of files run: yarn eslint {staged_files} # {staged_files} or {all_files} - list of files
-
自定义列表
pre-push: commands: frontend-style: files: git diff --name-only master # files with, diff with master. glob: "*.js" run: yarn stylelint {files}
独立的本地装备
虽然运用Git Hooks的目的是为了在几个开发人员作业时坚持代码库的质量,但人们可能需要一种方法来绕过它,在他们的本地机器上以不同方法履行特定的钩子。Lefthook经过增加一个独自的文件来支撑这种优化,以便在本地环境中以不同的方法办理Hooks。
让咱们创立一个commit-msg
钩子来更好地理解本地装备。运用下面的代码来创立一个新的钩子。
lefthook add -d commit-msg
增加-d
将创立.lefthook/commit-msg
和.lefthook-local/commit-msg
目录。第一个是用于普通的项目级脚本;第二个是用于个人脚本,当使命只在创立者的机器上本地运转时,这些脚本将被运用。抱负状况下,.lefthook-local
应该是.gitignore
的一部分。
脚本和运转器
运用Lefthook,你能够用任何编程言语创立自定义使命。这让咱们能够自由地优化 Git 钩子,使其更快。
除此之外,咱们还能够为这些脚本挑选运转器,比方Docker VM。下面是一个用Bash运转器处理自定义脚本的简略比方。
让咱们创立一个Bash脚原本查看.lefthook/commit-msg/template_checker
中的提交模板。
INPUT_FILE=$1
START_LINE=`head -n1 $INPUT_FILE`
PATTERN="^(ISSUE)-[[:digit:]]+: "
if ! [[ "$START_LINE" =~ $PATTERN ]]; then
echo "Bad commit message, see example: ISSUE-123: some text"
exit 1
fi
现在咱们能够经过在lefthook.yml
文件中增加这段代码来要求Lefthook运转咱们的Bash脚本。
commit-msg:
scripts:
"template_checker":
runner: bash
# "template_checker.js": # We can also use JS file and reference it here
# runner: node # It will be executed using node as a runner
# USING DOCKER AS RUNNER
# "docker_hook.js": # Similar file reference
# runner: docker run -it --rm <container_id_or_name> {cmd} # Here {cmd} => command
管道式履行
虽然并行履行是一个杰出的特色,Lefthook也支撑指令的管道履行。假如使命的履行需要管道化的功用,而序列中的任何指令都会失败,Lefthook就不会履行其他的指令,保证使命的顺利完成。
这关于那些需要在履行前进行数据库设置的使命来说是非常有协助的。下面是一个小比方。
database:
piped: true
commandy
1_create:
run: rake db:create
2_migrate:
run: rake db:migrate
3_seed:
run: rake db:seed
装备的承继
Lefthook中的装备设置不只限于本地和项目层面,咱们还能够扩展装备。
装备的承继有助于保证产品或公司范围内的提交信息、安全审计和其他查看的同步。下面是如何扩展任何其他装备。
extends:
- ~/unicorns/configs/lefthook-extend-2.yml
在React/React Native中完成Lefthook
假如上述比方对作为React或React Native开发者的你来说并不直观,请不要担心;以下是如何在你的运用中运用Lefthook的演示。
咱们将从装置Lefthook开端。
npm install @arkweid/lefthook --save-dev # or yarn add @arkweid/lefthook -D
一旦Lefthook装置完毕,你会在项目的根部看到lefthook.yml
;这是一个文件,它将包容咱们一切的作业和挂钩。记住,这是一个开发依赖性,是与本地或全球装置的Lefthook二进制文件的绑定。它把你从依赖关系的恶梦中解放出来。
替换Husky
本节假设你的运用程序已经集成了Husky;假如你的状况不是这样,请移到下一节。
从从你的项目中卸载Husky开端。
npm uninstall husky # or yarn remove husky
卸载后,你能够从项目中删去.husky
目录,或从package.json
中删去其声明,这取决于你的完成。
接下来,让咱们把Git Hooks重置为默认值。
git config --unset core.hooksPath
rm .git/hooks/pre-commit
rm .git/hooks/pre-push
现在,把Husky的完成移到lefthook.yml
。
pre-commit:
commands:
sometest:
run: npm lint
pre-push:
commands:
anothertest:
run: npm audit
预提交钩子
让咱们增加一个快速并行运转的预提交钩子,以保证咱们的运用程序的代码在开发者提交时总是适合被合并的。请保证你的运用程序中启用了TypeScript。
由于咱们已经装置了Lefthook(假如你从上面跳到这一节,请回顾之前的代码以取得装置协助),让咱们开端为咱们的运用增加一个预提交钩子。咱们把咱们的预提交钩子分红四个使命,一切这些使命都能够并行运转。
- 类型查看
- ESLint
- 代码拼写查看器
- 马克顿链接查看
下面是咱们的预提交钩子,一切四个使命都在并行运转。
pre-commit:
parallel: true
commands:
type-check:
glob: '*.{ts,tsx}'
run: yarn typecheck
eslint:
glob: '*.{js,ts,jsx,tsx}'
run: yarn lint:eslint:fix {staged_files}
stylelint:
glob: '*.{js,ts,jsx,tsx}' # For CSS-in-JS
run: yarn lint:style {staged_files}
spelling:
glob: '*.{js,ts,jsx,tsx,md}'
run: yarn cspell {staged_files}
markdown-link-check:
glob: '*.md'
run: npx markdown-link-check {staged_files}
正如你所看到的,咱们运用了Lefthook的才能,为使命履行挑选了一大块文件。文件的挑选取决于使命,例如,类型查看必须在整个运用程序中履行,以保证类型安全,而lint、拼写查看和链接查看只适合于分阶段的文件。
提交音讯钩子
接下来是提交音讯钩子。这个钩子为咱们省去了办理改变日志和提交信息可读性的麻烦。
咱们在这儿运用的是commitlint,但你也能够像前面提到的那样,运用其他库或你的自定义脚本与runners。下面是咱们的commit-msg
钩子的代码,看起来。
commit-msg:
commands:
parallel: true
lint-commit-msg:
run: npx commitlint --edit
spell-check:
run: yarn cspell --no-summary {1}
预推送钩子
现在,是时候保证每当代码被推送到咱们的库房时,它都经过了良好的质量和安全测试。就像咱们的预提交钩子一样,这些使命能够并行进行。下面是咱们的预推送钩子。
pre-push:
parallel: true
commands:
test:
run: yarn test
packages-audit:
run: yarn audit
一言以蔽之
在我看来,Lefthook比其他的Git Hook办理库更有力,同时也给了咱们更多的自由和简略。经过并行化,使命履行得更快,加上对自定义运转器的支撑,Lefthook是在CI/CD环境中运用的一个不错的挑选。装备的承继关于跨团队履行共同的编码实践有很大协助。
假如你对Lefthook形象深刻并希望从Husky迁移,这儿有迁移指南。
我还预备了一个Gist,能够把这儿评论的钩子增加到你的React和React Native运用中。请试一试吧。
The postA deep dive into Lefthook for React and React Nativeappeared first onLogRocket Blog.