在 git hooks 中运行 npm script

严肃的研发团队都会使用 Git 之类的版本管理系统来管理代码,随着 GitHub 的广受欢迎,相信大家对 Git 并不陌生。Git 在代码版本管理之外,也提供了类似 npm script 里 prepost 的钩子机制,叫做 Git Hooks,钩子机制能让我们在代码 commit、push 之前(后)做自己想做的事情。

Git Hooks 能给我们的开发工作流带来哪些可能呢?我带的团队中,大部分项目通过 npm script 为本地仓库配置了 pre-commit、pre-push 钩子检查,且正计划为远程仓库(Remotes)配置 pre-receive 钩子检查。两种钩子的检查目的各不相同,本地检查是为了尽早给提交代码的同学反馈,哪些地方不符合规范,哪些地方需要注意;而远程检查是为了确保远程仓库收到的代码是符合团队约定的规范的,因为如果没有远程检查环节,熟悉 Git 的同学使用 --no-verify(简写为 -n) 参数跳过本地检查时,本地检查就形同虚设。

可能有同学会嘀咕,在 IDE 里面配置各种检查难道还不够么?对个人开发者来说足够了,但对于团队,如果对代码里面的坏味道听之任之,久而久之整个团队的代码质量标准都会被拉低,到最后坑的还是团队的每个成员,不是么?之前没想到这层的同学建议去看看破窗理论。

那么增加 Git Hooks 的必要性聊清楚了,我们应该在 Git Hooks 里面做哪些事情呢?通常来说:检查编码规范,把低级错误趁早挖出来修好;运行测试,用自动化的方法做功能回归,测试本身就包含很多话题,且按下不表。

前端社区里有多种结合 npm script 和 git-hooks 的方案,比如 pre-commit、husky,相比较而言 husky 更好用,它支持更多的 Git Hooks 种类,再结合 lint-staged 试用就更溜。

接下来我们逐步给示例项目配置本地的 Git Hooks,而在钩子中运行的是已有的 npm script,比如 lint、test:

1. 安装项目依赖

使用如下命令安装 husky、lint-staged 到项目依赖中:

npm i husky lint-staged -D
# npm install husky lint-staged --save-dev
# yarn add husky lint-staged -D

husky 的基本工作原理可以稍作解释下,翻看 husky 的 package.json,注意其中的 scripts 声明:

  "scripts": {"test": "jest","format": "prettier --single-quote --no-semi --write **/*.js","install": "node ./bin/install.js","uninstall": "node ./bin/uninstall.js"},

这里面的 install 就是你在项目中安装 husky 时执行的脚本(所有的魔法都藏在在这里了,哈哈)。

然后再检查我们仓库的 .git/hooks 目录,会发现里面的钩子都被 husky 替换掉了,注意下图中三个红色框中的内容:

2. 添加 npm script

接下来需要在 scripts 对象中增加 husky 能识别的 Git Hooks 脚本:

   "scripts": {
+    "precommit": "npm run lint",
+    "prepush": "npm run test","lint": "npm-run-all --parallel lint:*","lint:js": "eslint *.js",

这两个命令的作用是在代码提交前运行所有的代码检查 npm run lint;在代码 push 到远程之前,运行 lint 和自动化测试(言外之意,如果测试失败,push 就不会成功),虽然运行的是 npm run test,但是 lint 也配置在了 pretest 里面。

然后尝试提交代码:git commit -am 'add husky hooks',能看到 pre-commit 钩子已经生效:

3. 用 lint-staged 改进 pre-commit

如上的配置乍看起来没有任何问题,但是在大型项目、遗留项目中接入过 lint 工作流的同学可能深有体会,每次提交代码会检查所有的代码,可能比较慢就不说了,接入初期 lint 工具可能会报告几百上千个错误,这时候估计大多数人内心是崩溃的,尤其是当你是新规范的推进者,遇到的阻力会增大好几倍,毕竟大多数人不愿意背别人的锅,坏笑。

好在,我们有 lint-staged 来环节这个问题,每个团队成员提交的时候,只检查当次改动的文件,具体改动如下:

   "scripts": {
-    "precommit": "npm run lint",
+    "precommit": "lint-staged","prepush": "npm run test","lint": "npm-run-all --parallel lint:*",},
+  "lint-staged": {
+    "*.js": "eslint",
+    "*.less": "stylelint",
+    "*.css": "stylelint",
+    "*.json": "jsonlint --quiet",
+    "*.md": "markdownlint --config .markdownlint.json"
+  },"keywords": [],

接下来我们故意在 index.js 中引入错误:

-  return NaN;
+  return NaN

然后尝试提交这个文件:git commit -m 'try to add eslint error' index.js,结果如下图:

上图中带有 Running Tasks 字样的列表就是 lint-staged 根据当前要提交的文件和 package.json 中配置的检查命令去执行的动态输出。红色框里面提示 husky 的 pre-commit 钩子执行失败,提交也就没有成功。

关于 lint-staged 还有些高级的用法,比如对单个文件执行多条命令,对单个文件动态自动修复,自动格式化等等,留待大家自己去探索好了。

撤销掉有错误的修改,提交之后,我们往远程 push 新分支,结果如下图:

读过我其他文章的同学可能已经想到,本小节的内容部分和我早期的文章《用 husky 和 lint-staged 构建超溜的代码检查工作流》有部分内容是重叠的。


本节用到的代码见 GitHub,想边看边动手练习的同学可以拉下来自己改(记得安装 npm 依赖之后再运行脚本),注意切换到正确的分支 11-run-npm-script-in-git-hooks


上一篇:实战篇 02:结合 live-reload 实现自动刷新下一篇:实战篇 04:用 npm script 实现构建流水线

在 git hooks 中运行 npm script相关推荐

  1. 监听文件变化并自动运行 npm script

    监听文件变化并自动运行 npm script 软件工程师做的事情基本都是在实现自动化,比如各种业务系统是为了业务运转的自动化,部署系统是为了运维的自动化,对于开发者本身,自动化也是提升效率的关键环节, ...

  2. 用 npm script 实现构建流水线

    用 npm script 实现构建流水线 在现代前端项目的交付工作流中,部署前最关键的环节就是构建,构建环节要完成的事情通常包括: 源代码预编译:比如 less.sass.typescript: 图片 ...

  3. 实现 npm script 跨平台兼容

    实现 npm script 跨平台兼容 到目前为止,如果你在 Linux.Mac 平台做开发,所有的 npm script 都会顺利运行,但是 Windows 下面的同学可能就比较痛苦了,因为不是所有 ...

  4. 在 npm script 中使用环境变量

    在 npm script 中使用环境变量 npm 为加高效的执行 npm script 做了大量的优化,创建并运行 npm script 命令 里面讲到的环境变量特性能让我们在 npm script ...

  5. 把庞大的 npm script 拆到单独文件中

    把庞大的 npm script 拆到单独文件中 当 npm script 不断累积.膨胀的时候,全部放在 package.json 里面可能并不是个好主意,因为这样会导致 package.json 糟 ...

  6. npm script 的实践

    打包环节 要实现 假设我们的项目结构是这样的 src ├── images │ ├── a.png │ └── b.png ├── index.html ├── scripts │ └── index ...

  7. 给 npm script 传递参数和添加注释

    给 npm script 传递参数和添加注释 本小节会介绍 3 个知识点:给 npm script 传递参数以减少重复的 npm script:增加注释提高 npm script 脚本的可读性:控制运 ...

  8. 初识 npm script : 用 npm init 快速创建项目

    初识 npm script 首先介绍创建 package.json 文件的科学方法,目标是掌握 npm init 命令.然后,通过在终端中运行自动生成的 test 命令,详细讲解 npm 脚本基本执行 ...

  9. 用 npm script 实现服务自动化运维

    用 npm script 实现服务自动化运维 需要事先说明的是,本节部分内容涉及到非前端的话题,比如服务的部署.日志,但会从前端项目管理开始,比如依赖管理.版本管理等.即使对自己定位是纯粹前端开发的同 ...

最新文章

  1. 浅淡绿萝2.0和星火计划
  2. 解决 swap file “*.swp”already exists!问题
  3. 使用 Canvas 生成公众号头图
  4. 阿里云MaxCompute(大数据)公开数据集---带你玩转人工智能 1
  5. LeetCode 434. Number of Segments in a String
  6. JAVE amr转换mp3
  7. 原来可视化还能这么美...
  8. 奇思妙想,获取对方手机通信录
  9. 【历史上的今天】10 月 27 日:世界上第一次网络瘫痪;网络广告的诞生;短视频鼻祖 Vine 关闭
  10. 数字和模拟混合供电20190221
  11. PySimpleGUI经典实践之:这个汉字怎么读?
  12. 在线视频插上“大数据翅膀”
  13. 无粉丝无流量怎么加入快手小黄车?怎么开通小黄车?
  14. python进阶数据分析_数据分析--Part 2: Python进阶
  15. linuxoracle图形界面无法跳出_Linux 7图形化安装Oracle或者其他软件,打不开图形界面的问题 | 信春哥,系统稳,闭眼上线不回滚!...
  16. Bit、Byte、KB、MB(M)、GB(G)关系
  17. NOIp2018 pj 滚粗记
  18. 纳米结构中的磁斯格明子
  19. 中国生态足迹与生物承载力数据(1961-2016年)
  20. 使用Python生成双色球号码

热门文章

  1. 优秀的 jQuery 文本输入框自动完成 自动提示插件
  2. magento 获取 pages/Static Block 内容 Get Pages/Static Block in Magento
  3. 国家和货币(符号/图片)数组(countries and currency symbol array)
  4. C++ const用法 尽可能使用const
  5. CentOS下使用rpm-build制作nginx的RPM包
  6. varnish 高性能方向代理服务器
  7. Vi和Vim的区别和联系
  8. 【CVPR2019】Workshops 研讨会列表及链接
  9. 【实习生笔试面试题】2013年搜狐SOHU实习生技术笔试题
  10. 【Linux】进程间通信-命名管道FIFO