从commit校验失效问题探究husky原理

一、背景

之前创建的项目,发现代码 commit 提交的时候没有了任何校验,具体表现:

  • 一是 feat fix 等主题格式校验没有了
  • 二是代码 lint 不通过也能提交

尝试解决这个问题,并深入了解husky的实现原理,将相关的一些知识点分享下。

二、lint配套工具

完整的一套代码规范工具,可能包含:husky + lint-staged + eslint + stylelint + prettier

1. git 钩子:

git 本身提供多个生命周期钩子,常见的例如 pre-commit、commit-msg、pre-push 等。

pre-commit 钩子:

在 git commit 命令执行之前触发,配合指定的脚本命令可用来执行代码 lint 校验、代码格式化、跑测试用例等任务,以确保在提交代码之前达到一定的质量标准。

commit-msg 钩子:

是在 git 编辑提交信息之后、提交之前触发,可用于 commit 信息的格式校验。

2. husky:

husky 是一个用来简化 Git 钩子管理的工具。它可以帮助你在 Git 的生命周期事件(如 pre-commit、pre-push 等)中轻松地添加脚本,并且与常用的 js 工具和任务管理器(npm、yarn)集成良好。

3. lint-staged:

lint-staged 用于结合 husky 和 pre-commit,能做到只对 Git 暂存区(git add . 之后)的文件 运行校验任务,从而实现只处理改动的文件,提升commit效率,在大型项目上效果更加明显。

4. eslint:

eslint 是用于对 js 和 jsx 做代码校验的工具,通过静态分析代码来快速地发现和修复一些代码语法问题,帮助前端开发规范代码、提高效率。

5. stylelint:

stylelint 是用于对 css 样式 做代码校验的工具,同上述 eslint 类似,帮助前端开发在编写 css 及 less等预处理器代码时避免犯错,提升开发效率。

6. prettier:

prettier 是目前最常用的前端代码格式化工具,支持多项规则配置,帮助统一代码风格。适当的配置后可以与上述 eslint 和 stylelint 兼容。

三、husky原理

疑问:

  • git 是全局命令,而 husky 只是项目里引入的一个插件,它是怎么和全局的 git 命令产生联系的?
  • 我们通过 git commit -m “xxx” 提交代码时,husky 做了什么?

(以下以 mac os 下 husky v9 版本示例)

1. husky初始化:

1)配置方式:
  • 一般会在项目 package.json 的 scripts 里配置下 prepare 命令(“prepare”: “husky”),用于执行 husky 的初始化。prepare 是 npm 的钩子,在项目 npm i 时会自动执行 npm run prepare。
2)解析husky命令:
  • 执行 husky 命令 实际就是执行 node_modules/.bin/husky 文件,里面没啥东西,主要是三块,自动修改 husky init 命令、错误命令输出处理、执行 index.mjs,显然核心代码在 index.mjs 里。
  • 找到 node_modules/husky/index.mjs 文件,解析下里面的核心代码动作:
    • 执行命令 git config core.hooksPath .husky/_ ,创建目录 .husky/_
    • .husky/_ 里写入 .gitignore 内容为 *
    • 复制 node_modules/husky/husky 文件内容到 .husky/_ 的 h 文件
    • 遍历 l 数组,即支持的所有 git 钩子,复制到 .husky/_ 下同名文件,内容统一为 . “${0%/*}/h”
    • .husky/_ 里创建文件 husky.sh,内容为空。
3)解析说明:
  • 一般来说项目都是用 git 来作为代码版本控制工具,每个项目在 git init 初始化后,根目录都会生成一个 .git 隐藏文件夹,里面是 git 的配置文件 及 代码记录信息。

  • husky 在执行初始化命令后,会自动修改 git 的 hooks 目录,具体表现为在项目 .git 文件夹下的 config 文件里新增了 core.hooksPath 配置,指向项目的 .husky/_ 目录,这样执行 git commit 命令时就会自动寻找项目 .husky/_ 下的钩子文件。

    • 未指定时,默认的 hooks 目录是 .git/hooks
    • 在这里插入图片描述
  • 然后在 .husky/_ 目录下自动生成 git 钩子文件 和 一些执行脚本。
    *

2. husky执行流程:

(以项目 pre-commit 钩子为例)

1)开始运行 commit
  • 修改项目文件,运行 git add .
  • 运行 git commit -m “xxx”,开始流程。
2)读取 hooks 目录配置
  • git工具会去项目的 .git 目录 config 文件里读取 core.hooksPath 目录配置,指向了.husky/_ 目录
3)寻找 pre-commit 业务脚本
  • 首先在 .husky/_ 目录下找到 pre-commit 钩子文件,即 .husky//pre-commit,并执行,实际执行是指向了同目录下的 h 文件,即 .husky//h
    • ${0%/*}:0表示当前执行的脚本路径,%/* 表示从字符串末尾匹配 /*,保留前面部分
  • 执行 h 文件,里面基本是统一读取 husky 配置 以及 做了错误校验,然后实际执行是指向了上一级目录下的同名文件,即 .husky/pre-commit,这个就是我们要寻找的业务侧钩子脚本。
    • ${0##*/}:##/* 表示最大化匹配 */,保留后面部分
4)执行 pre-commit 脚本
  • 执行 .husky/pre-commit 文件,这个就是真正的业务侧钩子脚本,里面内容是就是跑 lint-staged。
5)执行 lint-staged 脚本
  • 运行 lint-staged 命令时,首先是要读取 lint-staged 配置,在 .lintstagedrc 文件里(部分项目可能在 package.json 里配置的),里面就是对不同类型的文件跑不同的命令
    • 在这里插入图片描述
6)执行成功 or 失败
  • 如果命令执行成功,pre-commit 钩子就顺利执行完成了,接着会往下走流程,走 commit-msg 钩子,做 提交信息的格式校验,大致流程类似。
  • 如果执行异常,钩子会中断,不会往下走,commit 失败。如异常命令有抛出信息会在命令行输出。

四、问题解决:

回到最初提到的 bigfish 项目 commit 失效问题。

1. 问题原因:

在代码提交时有warning提示,翻译下来就是 .husky 文件夹下的两个文件是不可执行的,

其实就是 .husky 里的这两个钩子文件没有被赋予可执行权限。

  • 如果这俩文件是在Windows下创建后上传的,在mac下把项目拉下来后就不可执行了。

2. 解决方式:

方式一:

  • 在项目根目录下运行命令,给钩子文件手动赋予可执行权限,
    • chmod +x .husky/commit-msg .husky/pre-commit

方式二:(推荐)

  • 升级 husky 版本到 v9,修改 package.json 里的 preare 命令为 “husky”,然后运行 npm run prepare
    • husky v9 版本更新日志里有一项变更,通过自动设置正确的文件权限,解决了 husky v8 中的这个权限问题。

3. 全局format:

解决完后,建议执行一次 npm run format 命令,即 prettier,对全局做一次代码格式化。
因为每次 commit 校验的时候项目虽然会自动执行 format,但只对修改的文件执行,建议提前对项目所有文件 format 处理下。

五、IDE自带git工具问题:

可能有些人会遇到使用 vscode 或 在线编辑器 等IDE时,自带的 git 管理工具无法 commit,执行时会立即报错。

1. 问题原因:

可能你使用了 nvm 等 node 管理工具,使用 git 工具可能会无法 commit,原因是执行 husky 命令时识别不出 node 环境,详见链接,需要补充环境配置。

2. 解决方式:

在 .husky/pre-commit 和 .husky/commit-msg 文件内容里的 npx执行命令 之前,添加环境配置代码:

待添加的环境配置代码内容:

  • 方式一:(个人搜寻并组合出来的)
if [ -s "$HOME/.nvm/nvm.sh" ]; then# First load nvm and provide access to the nvm command.export NVM_DIR="$HOME/.nvm/nvm.sh". "$(dirname $NVM_DIR)/nvm.sh"# Use the nvm ls command to detect the version being used.export NVM_DIR="$HOME/.nvm"a=$(nvm ls | grep 'node')b=${a#*(-> }v=${b%%[)| ]*}# Export the current version in your path for husky to find.export PATH="$NVM_DIR/versions/node/$v/bin:$PATH"
fi
  • 方式二:(官方文档里的,待验证)
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # 加载 nvm

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/881538.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Canvas与诗词】要做一棵树,站成永恒

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>要做一棵树站成永恒</title><style type"text/css&quo…

tauri开发Mac电脑Safari浏览器一个很奇怪的问题:在 input 输入框输入的是全小写英文字母,会自动将首字母转换为大写解决办法

问题原因 在 Mac 系统中默认使用 Safari 的内核 WKWebView 作为渲染引擎&#xff0c;而 Safari 浏览器的一些 “人性化” 机制&#xff1a;如果输入框中输入的是全小写英文&#xff0c;会自动将首字母转换为大写。 解决办法 我只需要禁止这个默认的行为&#xff0c;即可解决这…

STM32(十八):实时时钟

时间戳 Unix 时间戳&#xff08;Unix Timestamp&#xff09;定义为从UTC/GMT的1970年1月1日0时0分0秒开始所经过的秒数&#xff0c;不考虑闰秒。 时间戳存储在一个秒计数器中&#xff0c;秒计数器为32位/64位的整型变量。 世界上所有时区的秒计数器相同&#xff0c;不同时…

项目_C_Ncurses_Flappy bird小游戏

Ncurses库 概述 什么是Ncurses库&#xff1a; Ncurses是一个管理应用程序在字符终端显示的函数库&#xff0c;库中提供了创建窗口界面、移动光标、产生颜色、处理键盘按键等功能。 安装Ncurses库&#xff1a; sudo apt-get install libncurses5-dev 头文件与编译&#xf…

ECCV`24 | 新加坡国立华为提出Vista3D: 实现快速且多视角一致的3D生成

文章链接&#xff1a;https://arxiv.org/pdf/2409.12193 gitbub链接&#xff1a;https://github.com/florinshen/Vista3D 亮点直击 提出了Vista3D&#xff0c;一个用于揭示单张图像3D darkside 的框架&#xff0c;能够高效地利用2D先验生成多样的3D物体。开发了一种从高斯投影到…

初级学习:Python实现AI并搭建

随着人工智能(AI)的迅猛发展,越来越多的人希望能够学习如何通过编程实现AI应用。Python,因为其简洁易用,被广泛认为是AI开发的理想编程语言。本文将介绍Python在AI开发中的基础应用,帮助初学者入门并构建自己的AI项目。 为什么选择Python 在了解如何用Python实现AI之前,…

十、kotlin的协程

协程 基本概念定义组成挂起和恢复结构化并发协程构建器作用域构建器挂起函数阻塞与非阻塞runBlocking全局协程像守护线程 Job的生命周期 常用函数延时和等待启动和取消启动取消 暂停 协程启动调度器启动方式启动模式线程上下文继承的定义继承的公式 协程取消与超时取消挂起点取…

HTMLCSS练习

1) 效果如下 2) 代码如下 2.1) HTML <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" conte…

Windows系统编程(三)线程并发

进程与线程 进程&#xff1a;直观的说就是任务管理器中各种正在运行的程序。对于操作系统来说&#xff0c;进程仅仅是一个数据结构&#xff0c;并不会真实的执行代码 线程&#xff1a;通常被称作但并不真的是轻量级进程或实际工作中的进程&#xff0c;它会真实的执行代码。每…

设计模式之适配器模式(Adapter)

一、适配器模式介绍 适配器模式(adapter pattern )的原始定义是&#xff1a;将类的接口转换为客户期望的另一个接口&#xff0c; 适配器可以让不兼容的两个类一起协同工作。 适配器模式是用来做适配&#xff0c;它将不兼容的接口转换为可兼容的接口&#xff0c;让原本由于接口…

2024年1月Java项目开发指南18:自定义异常输出

一般情况下&#xff0c;报错信息一大堆&#xff0c;值得注意的只有三个地方&#xff1a; 哪个文件发生了错误哪一行发生了错误错误原因是什么 只要知道这三个东西就能快速的定位到错误发生的位置并且根据提示解决。 如果你也喜欢我的这种异常输出(如文章顶部图) 那么可以参考以…

[M数学] lc3164. 优质数对的总数 II(因数分解+倍增+推公式+思维+好题)

文章目录 1. 题目来源2. 题目解析 1. 题目来源 链接&#xff1a;3164. 优质数对的总数 II 2. 题目解析 挺不错的一道 因数分解、倍增 的题目&#xff0c;需要一定的思维和推公式的能力才能解决。灵神的题解已经非常清晰易懂了&#xff0c;可以直接去看。 倍增思路&#xff…

大数据分析案例-基于逻辑回归算法构建抑郁非抑郁推文识别模型

🤵‍♂️ 个人主页:@艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞👍🏻 收藏 📂加关注+ 喜欢大数据分析项目的小伙伴,希望可以多多支持该系列的其他文章 大数据分析案例合集

(十八)、登陆 k8s 的 kubernetes-dashboard 更多可视化工具

文章目录 1、回顾 k8s 的安装2、确认 k8s 运行状态3、通过 token 登陆3.1、使用现有的用户登陆3.2、新加用户登陆 4、k8s 可视化工具 1、回顾 k8s 的安装 Mac 安装k8s 2、确认 k8s 运行状态 kubectl proxy kubectl cluster-info kubectl get pods -n kubernetes-dashboard3、…

如何启动一个OpenSearch

创建两个集群&#xff0c;标注 不含备用节点 选择集群版本和配置集群版本 冷热存储和专用主节点这个按需开启 然后是网络&#xff0c;是否使用自定义域名&#xff0c;集群开在VPC还是公网上。 选择是否开启认证&#xff1a; 访问策略&#xff0c;其实就是资源策略 维护时段…

Oracle 数据库安装和配置详解

Oracle 数据库安装和配置详解 Oracle 数据库是一款功能强大、广泛使用的企业级关系数据库管理系统 (RDBMS)&#xff0c;适用于处理大型数据库和复杂事务。本文将介绍如何在 Linux 和 Windows 环境下安装 Oracle 数据库&#xff0c;并对其进行基本配置&#xff0c;帮助开发者快…

理解计算机系统_程序的机器级表示(特别篇):对比move和leaq看汇编语言中数据的传递,变量和指针的映射,指针的实现

前言 以<深入理解计算机系统>(以下称“本书”)内容为基础&#xff0c;对程序的整个过程进行梳理。本书内容对整个计算机系统做了系统性导引,每部分内容都是单独的一门课.学习深度根据自己需要来定 引入 汇编代码传递数据的机制令人费解.而这部分内容又是比较基础的,需要…

实例详解 | 借助 Langchain 和 Gemma 2 构建 RAG 应用

本文原作者&#xff1a;Connie Leung&#xff0c;谷歌开发者专家 (GDE)&#xff0c;原文发布于&#xff1a;DEV Community https://dev.to/railsstudent/build-a-rag-application-to-learn-angular-using-langchhtainjs-nestjs-htmx-and-gemma-2-5ggk 本文将为您介绍如何使用…

.Net基础1

.NET框架 项目结构 Connected Services是第三方服务MVC框架appsettings.json配置文件Program.cs控制台应用程序Properties里的json文件是配置启动方式 1. 基本开发 出现这个bug是因为防火墙没有把浏览器加入白名单&#xff0c;可以暂时先用http启动代替 第一步创建控制器&am…

数字化AI新赋能,智享AI直播:开启一个全新的直播时代!

数字化AI新赋能&#xff0c;智享AI直播&#xff1a;开启一个全新的直播时代! 在科技日新月异的今天&#xff0c;人工智能&#xff08;AI&#xff09;技术正以前所未有的速度改变着我们的生活和工作方式。其中&#xff0c;AI直播技术的崛起&#xff0c;无疑是数字化时代的一大亮…