为什么husky哈士奇放弃了传统的 JS 配置(翻译)
关于我最喜欢的哈士奇新功能以及导致它的原因的简短说明。
背景
我在 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 发生变化时,您(和您的合作者)都需要重新生成钩子。重新生成可能与某些事件绑定,但没有可靠的方法来涵盖所有可能的情况,并且会出现意外行为。这就是为什么这种方法被驳回的原因。
哈士奇新方法
当你的抽象有缺陷时,通常是退步的信号。
到目前为止,我们知道什么?
- 按照设计,Git 挂钩配置是通过可执行脚本完成的。
- 哈士奇最初的方法是一种间接的方法和一点魔法。
- 从 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
中的一行并运行一个命令来添加一个钩子(仅此而已)。
这与 jest
、eslint
的步骤数相同……将命令添加到 package.json
并创建一个文件 .jestrc.js
、.eslintrc.js
、……
(不过只有一个例外,如果您要发布一个包并同时使用 Yarn v2,则需要三行)
“如果有
core.hooksPath
,为什么还要使用 husky?”
Husky 提供了一些基于以前版本反馈的安全防护、用户友好的错误消息和一些附加功能。这是完全原生和一点用户友好性之间的平衡。
“迁移会很复杂。”
有 husky-4-to-6 CLI 会自动为您完成。
…但我仍然想在 package.json 中定义钩子
好消息!没有什么能阻止你这样做
为什么husky哈士奇放弃了传统的 JS 配置(翻译)相关推荐
- 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 ...
- vue-cli3中的vue.config.js配置
vue-cli3中的vue.config.js配置 我的跨域是配置通过chrome浏览器的跨域设置,前端修改跨域问题,以此解决跨域的,故没有配置代理: const path = require('pa ...
- Vue Cli3 项目 vue.config.js 配置
Vue Cli3 项目 vue.config.js 配置 配置优化 一.js文件最小化处理 二.分割代码 三.图片资源压缩 四.开启gzip压缩 先看一下优化配置之前的文件大小 通过vue-cli3脚 ...
- 【vue.config.js配置configureWebpack的optimization splitChunks页面空白 - DCloud】
vue.config.js配置configureWebpack的optimization splitChunks页面空白 - DCloud问答
- 【Cli下在vue.config.js配置configureWebpack/resolve/alias之无效 - 】
cli下在vue.config.js配置configureWebpack/resolve/alias无效 - DCloud问答
- vue.config.js配置configureWebpack的optimization splitChunks页面空白
确实通过这种方式解决: vue.config.js配置configureWebpack的optimization splitChunks页面空白 - DCloud问答 原因可能是这个: Taro项目 ...
- vue 和 ssr+nuxt.js 配置环境变量以及pm2进行服务部署
前言 vue-ssr+nuxt.js开发的跨境电商的配置的项目环境变量. nuxt.js配置环境变量 第一步:安装cross-env插件 npm install cross-env --save 第二 ...
- 基于PHP美食食谱的外文翻译,中国传统菜谱的英文翻译锦集
中国传统菜谱的英文翻译锦集 第1部分.素菜类Vegetarian 1.豪油冬菇Oyster Sauce Mushroom 2.什笙上素Bamboo Vegetable 3.红烧豆腐Fried Tofu ...
- js摩斯密码翻译代码
js实现摩斯密码翻译功能,js摩斯密码翻译代码教程如下: 随机输入一些字符 实现结果:转换成摩斯密码 js实现代码如下: // 缂栫爜 $("#encode").click(fun ...
最新文章
- 掌握ConstraintLayout(十)按比例设置视图大小
- bat 复制文件夹_Windows批量创建文件夹:用Excel和记事本这2个就够了
- Appium 与 Chromedriver
- anglar ajax执行2次的原因,AngularJS与Ajax表单提交需要单击两次
- layui实现select下拉选择框组件(含代码、案例、截图)
- 1137.第N个泰波那契数
- iPhone 12系列全新渲染图曝光:4个“杯型” 起售价可能不到5k
- c#获取带有汉字的字符串长度
- Git(1):一个能够快速下载Git.exe的方法
- 配置文件中的后缀dev、test和prod是什么意思
- HTML与CSS如何创建悬停折角纸叠效果
- win7老计算机,windows7旗舰版系统电脑老是自动重启的原因汇总
- 用js实现在文本框中检测字数和限制字数功能
- 本地存储-系统和保留-系统文件占用存储空间过大的解决方式
- Python(爬虫篇)--- 破解加密【一】JS加密破解
- [JavaScript] audio在浏览器中自动播放
- tensorflow输出的人脸图片经过OpenCV write的图片是蓝色的问题的解决方案
- 智能PID软件-AVEVA Diagrams设备符号导入
- OpenSSL密码库算法笔记——第5章 椭圆曲线
- 说一说用户思维!!!