关于我最喜欢的哈士奇新功能以及导致它的原因的简短说明。

背景

我在 husky 上工作了 7 年,解决了 600 个与 JavaScript 项目中的 Git hooks 相关的问题。 1 月份,大约 100 个问题与新版本一起关闭。

从 v0 开始,husky 使用 JavaScript 配置 Git 挂钩,可以使用 .huskyrc.js 文件或 package.json 中的字段。

现在 Git 钩子是使用 .husky/ 目录中的钩子的单个文件配置的。

为什么突然改变?

一切都在变化和发展。 JS 生态系统已经发生了变化(yarn 已经被引入,monorepos 成为一种趋势,新工具和最佳实践出现了,甚至 npm 的工作方式也略有不同……)并且 Git 引入了一个令人兴奋的新功能。

但在谈论新配置及其好处之前,让我们先看看 husky 到目前为止所采取的方法。

哈士奇是如何工作的

以一种非常 Linux 的方式,要配置 Git 挂钩,您只需将可执行文本文件放在 .git/hooks/ 中。

为了能够运行用户在 .huskyrc.js 中创建的任何 Git 钩子,husky 将所有可能的钩子安装在.git/hooks/中。

例如,当提交时,每个 Git 钩子都会检查 .huskyrc.js 中是否有相应的钩子定义:

$ git commitpre-commit (native) → husky/runner.js (node)→ is a pre-commit defined in `.huskyrc.js`? → YES, run itprepare-commit-msg (native) → husky/runner.js (node)→ is a prepare-commit-msg defined in `.huskyrc.js`? → NO, do nothingcommit-msg (native) → husky/runner.js (node)→ is a commit-msg defined in `.huskyrc.js`? → NO, do nothingpost-commit (native) → husky/runner.js (node)→ is a post-commit defined in `.huskyrc.js`? → NO, do nothing

它的好处:用户可以从 .huskyrc.js 添加、更新和删除钩子,并且会自动选择更改。

不利的一面是,即使没有任何东西可以运行,node也会启动。

但是你可能会问,我们不能只安装所需的钩子吗?这是三年前设想的(#260),但哈士奇不再“自动工作”了。

例如,让我们考虑以下配置:

// .huskyrc.js
// .huskyrc.js
module.exports = {hooks: {'pre-commit': 'cmd'}
}
.git/hooks/pre-commit ← 以某种方式创建

然后你修改它:

// .huskyrc.js
// .huskyrc.js
module.exports = {hooks: {// 'pre-commit': 'cmd', ← removed'commit-msg': 'cmd'     ← added}
}

您的 .git/hooks 目录现在不一致:

.git/hooks/pre-commit ← 仍然存在
.git/hooks/commit-msg ← 不存在

由于你的钩子定义不再在一个地方,而是在两个地方(.huskyrc.js 和 .git/hooks/),突然你需要样板来保持 JS 世界与 Git 世界同步。

每次 .huskyrc.js 发生变化时,您(和您的合作者)都需要重新生成钩子。重新生成可能与某些事件绑定,但没有可靠的方法来涵盖所有可能的情况,并且会出现意外行为。这就是为什么这种方法被驳回的原因。

哈士奇新方法

当你的抽象有缺陷时,通常是退步的信号。

到目前为止,我们知道什么?

  1. 按照设计,Git 挂钩配置是通过可执行脚本完成的。
  2. 哈士奇最初的方法是一种间接的方法和一点魔法。
  3. 从 JS 配置生成 Git 钩子可能会不同步。

我们可以用 Git 做得更好吗?

2016 年,Git 2.9 引入了 core.hooksPath。它让你告诉 Git 不要使用 .git/hooks/ 而是另一个目录。

这就是新哈士奇的基础:

husky install 命令告诉 Git 使用 .husky/ 作为 Git hooks 目录。
husky add 创建一个带有小包装器的独立 shell 脚本来支持一些附加功能。
它解决了第一个问题(不必要的 Git 挂钩)和第二个问题(将挂钩定义放在单独一个地方)。

换句话说,当你用新的 husky 创建一个 hook 时,它是纯 shell 并且可以直接访问。 Git 和你之间再也没有什么了❤️。我觉得很漂亮。

但…

“有目录并不常见。”

这取决于,其他工具使用目录来存储配置。例如,一个 repo 可以有以下目录 .vscode/, .github/, .storybook/, …

从技术上讲,它只是树层次结构中的另一个条目。 .husky/ 目录不会比 .huskyrc.js 文件增加更多的视觉混乱。

这也是 Git 钩子的设计方式,也是 husky 遵循这种方法的原因。

但是,您可以选择放置 .husky/ 的位置。例如,它可以在 config/ 中与其他配置文件分组,供那些愿意的人使用。

“像 Jest、ESLint、Prettier 等 JS 工具都是用 JS config 配置的,husky 是一个 JS 工具。”

你可以拥有 .jestrc.js、.eslintrc.js、.prettierrc.js,这是有道理的,因为它们完全是用 JS 编写的。

但是 husky 是个特例,它不是纯 JS,它是“混合”的。它与已经可以配置的非 JS 工具交互。

“设置起来更难。”

Husky 带有一个init命令(推荐),你可以在几秒钟内完成。

$ npx @husky/init # 完成!

也就是说,手动设置 husky 只需要完成一次。您必须更改 package.json 中的一行并运行一个命令来添加一个钩子(仅此而已)。

这与 jesteslint的步骤数相同……将命令添加到 package.json 并创建一个文件 .jestrc.js.eslintrc.js、……

(不过只有一个例外,如果您要发布一个包并同时使用 Yarn v2,则需要三行)

“如果有 core.hooksPath,为什么还要使用 husky?”

Husky 提供了一些基于以前版本反馈的安全防护、用户友好的错误消息和一些附加功能。这是完全原生和一点用户友好性之间的平衡。

“迁移会很复杂。”

有 husky-4-to-6 CLI 会自动为您完成。

…但我仍然想在 package.json 中定义钩子

好消息!没有什么能阻止你这样做

为什么husky哈士奇放弃了传统的 JS 配置(翻译)相关推荐

  1. vue-cli的webpack模版,相关配置文件dev-server.js与webpack.config.js配置解析

    1.下载vue-cli [html] view plain copy npm install vue-cli -g vue-cli的使用与详细介绍,可以到github上获取https://github ...

  2. vue-cli3中的vue.config.js配置

    vue-cli3中的vue.config.js配置 我的跨域是配置通过chrome浏览器的跨域设置,前端修改跨域问题,以此解决跨域的,故没有配置代理: const path = require('pa ...

  3. Vue Cli3 项目 vue.config.js 配置

    Vue Cli3 项目 vue.config.js 配置 配置优化 一.js文件最小化处理 二.分割代码 三.图片资源压缩 四.开启gzip压缩 先看一下优化配置之前的文件大小 通过vue-cli3脚 ...

  4. 【vue.config.js配置configureWebpack的optimization splitChunks页面空白 - DCloud】

    vue.config.js配置configureWebpack的optimization splitChunks页面空白 - DCloud问答

  5. 【Cli下在vue.config.js配置configureWebpack/resolve/alias之无效 - 】

    cli下在vue.config.js配置configureWebpack/resolve/alias无效 - DCloud问答

  6. vue.config.js配置configureWebpack的optimization splitChunks页面空白

    确实通过这种方式解决: vue.config.js配置configureWebpack的optimization splitChunks页面空白 - DCloud问答 原因可能是这个: Taro项目 ...

  7. vue 和 ssr+nuxt.js 配置环境变量以及pm2进行服务部署

    前言 vue-ssr+nuxt.js开发的跨境电商的配置的项目环境变量. nuxt.js配置环境变量 第一步:安装cross-env插件 npm install cross-env --save 第二 ...

  8. 基于PHP美食食谱的外文翻译,中国传统菜谱的英文翻译锦集

    中国传统菜谱的英文翻译锦集 第1部分.素菜类Vegetarian 1.豪油冬菇Oyster Sauce Mushroom 2.什笙上素Bamboo Vegetable 3.红烧豆腐Fried Tofu ...

  9. js摩斯密码翻译代码

    js实现摩斯密码翻译功能,js摩斯密码翻译代码教程如下: 随机输入一些字符 实现结果:转换成摩斯密码 js实现代码如下: // 缂栫爜 $("#encode").click(fun ...

最新文章

  1. 掌握ConstraintLayout(十)按比例设置视图大小
  2. bat 复制文件夹_Windows批量创建文件夹:用Excel和记事本这2个就够了
  3. Appium 与 Chromedriver
  4. anglar ajax执行2次的原因,AngularJS与Ajax表单提交需要单击两次
  5. layui实现select下拉选择框组件(含代码、案例、截图)
  6. 1137.第N个泰波那契数
  7. iPhone 12系列全新渲染图曝光:4个“杯型” 起售价可能不到5k
  8. c#获取带有汉字的字符串长度
  9. Git(1):一个能够快速下载Git.exe的方法
  10. 配置文件中的后缀dev、test和prod是什么意思
  11. HTML与CSS如何创建悬停折角纸叠效果
  12. win7老计算机,windows7旗舰版系统电脑老是自动重启的原因汇总
  13. 用js实现在文本框中检测字数和限制字数功能
  14. 本地存储-系统和保留-系统文件占用存储空间过大的解决方式
  15. Python(爬虫篇)--- 破解加密【一】JS加密破解
  16. [JavaScript] audio在浏览器中自动播放
  17. tensorflow输出的人脸图片经过OpenCV write的图片是蓝色的问题的解决方案
  18. 智能PID软件-AVEVA Diagrams设备符号导入
  19. OpenSSL密码库算法笔记——第5章 椭圆曲线
  20. 说一说用户思维!!!

热门文章

  1. 蓝桥杯:报时问题(c语言)
  2. 《牛奶可乐经济学》---机会成本
  3. 2015年第7本(英文第6本):纳尼亚传奇I–狮子、女巫、魔衣橱
  4. 康佳d550 java_康佳 D550:整体外观图
  5. 【Java集合】List接口常用方法及实现子类
  6. java内部模型,13 张图拆解 Java 中的内存模型
  7. Vue学习--子组件向父组件传值
  8. requireJs快速上手
  9. 北风:利用微信红包封面怎么引流和变现(案例)
  10. jquery学习笔记及常用函数封装