vue-cli创建的项目中的gitHooks原理解析


Posted in Javascript onFebruary 14, 2020

前言

在使用 vue create my-app 创建项目的时候,Vue 会自动帮我们做好一些预配置,你可以不使用它,但是一旦需要的时候,突然发现,咦~原来它已经帮我做好准备工作了,只需要按自己的需求配置一下就可以了,就会觉得 vue-cli 很贴心啊,帮我们节省了很多时间。

package.json 文件中会发现 gitHookslint-staged 等字段,不难看出它是在我们执行 git 命令的时候会自动执行的一些额外的操作,比如语法提示、错误提示等。

这个完整的过程是怎样的呢?

流程解析

yorkie 包

执行 vue create 命令的时候,会安装一个包,叫: yorkie ,这个包是尤大 fork 自 husky 的,它俩功能是一样的,都是生成一些 git hooks 文件,读取项目中 package.json 的相关配置项去执行一些命令,区别是尤大做了一些逻辑和配置上的改动。

安装完这个包以后,会自动执行 yorkie 包里面的一个脚本: bin/install.js

vue-cli创建的项目中的gitHooks原理解析

这个脚本会在你项目下的 .git/hooks 目录中生成很多 git hooks 文件:

vue-cli创建的项目中的gitHooks原理解析

当你执行一些 git 命令的时候,比如: git push, git commit 等,git 就会执行相应的 hook。

package.json

git commit -a -m'123' 这个命令为例子,执行这个命令的时候,git 会去执行 pre-commit 这个 hook。

先把 package.json 的相关内容贴出来,让大家先有个印象:

"gitHooks": {
 "pre-commit": "lint-staged",
},
"lint-staged": {
 "*.{js,jsx,vue}": [
 "vue-cli-service lint",
 "git add"
 ]
}

pre-commit hook

接下来我们看 pre-commit 的文件内容:

##...
has_hook_script () {
 [ -f package.json ] && cat package.json | grep -q "\"$1\"[[:space:]]*:"
}
# 检查 package.json 文件中是否定义了 pre-commit
has_hook_script pre-commit || exit 0

# 运行 hook 
node "./node_modules/yorkie/src/runner.js" pre-commit || {
 echo
 echo "pre-commit hook failed (add --no-verify to bypass)"
 exit 1
}

可以看到 pre-commit 文件去检查了一下 package.json 文件中是否定义了pre-commit,如果定义了,就执行 yorkie 的 runner.js 脚本。

yorkie 的 runner.js 脚本

我们继续看 runner.js 脚本的内容:

//...
const cwd = process.cwd()
const pkg = fs.readFileSync(path.join(cwd, 'package.json'))
// 取到 package.json 里面定义的 gitHooks 内容
const hooks = JSON.parse(pkg).gitHooks
if (!hooks) {
 process.exit(0)
}
// 从上文得知,这个值是 pre-commit
const hook = process.argv[2]
// 取 gitHooks 里面定义的 pre-commit 的内容,也就取到:lint-staged
const command = hooks[hook]
if (!command) process.exit(0)
// 执行 lint-staged 命令
execa.shellSync(command, { stdio: 'inherit' })

从这个过程中可以看到,当我们执行 git commit -a -m'123' 这个 git 命令的时候,git hook 执行了 yorkie 的一个脚本去读取了 package.json 文件中的内容,取到相关的配置项,然后执行配置项中的命令。

在上述例子中,因为执行了 lint-staged 命令,它会读取 package.json 中的 "lint-staged" 配置项,进而又继续执行了 vue-cli-service lint 这个命令,整个执行的过程就像像链条一样一环连着一环,直到所有命令都执行完毕。

实践

明白了这个流程后,在项目中就可以根据需求灵活地做一些配置了,比如在执行 commit-msg hook 的时候加上 commitlint ,规范协作者提交的git 信息,加上这个以后,执行之前的示例命令: git commit -a -m'123' 就会有提交信息不规范的错误提示,根据提示改成: git commit -a -m'feat: 123' 就可以提交了。

同样的,与 pre-commit 搭配使用的 lint-staged ,也可以加上一些命令,比如这里加了 pretty-quick 用来统一代码格式。

示例:

"gitHooks": {
 "pre-commit": "lint-staged",
 "commit-msg": "commitlint -E GIT_PARAMS"
},
"lint-staged": {
 "*.{js,jsx,vue}": [
 "pretty-quick --staged",
 "vue-cli-service lint",
 "git add"
 ]
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 浏览器检测代码精简版
Mar 04 Javascript
前台js调用后台方法示例
Dec 02 Javascript
jquery获取tr并更改tr内容示例代码
Feb 13 Javascript
FF(火狐)浏览器无法执行window.close()解决方案
Nov 13 Javascript
使用js获取图片原始尺寸
Dec 03 Javascript
jquery表单验证需要做些什么
Nov 17 Javascript
深入解析Backbone.js框架的依赖库Underscore.js的作用
May 07 Javascript
jquery处理checkbox(复选框)是否被选中实例代码
Jun 12 jQuery
JS简单实现动态添加HTML标记的方法示例
Apr 08 Javascript
解决vuejs 使用value in list 循环遍历数组出现警告的问题
Sep 26 Javascript
vue中promise的使用及异步请求数据的方法
Nov 08 Javascript
详解将微信小程序接口Promise化并使用async函数
Aug 05 Javascript
基于vue的tab-list类目切换商品列表组件的示例代码
Feb 14 #Javascript
bootstrap-paginator服务器端分页使用方法详解
Feb 13 #Javascript
JavaScript实现Tab选项卡切换
Feb 13 #Javascript
Angular 多模块项目构建过程
Feb 13 #Javascript
小程序卡片切换效果组件wxCardSwiper的实现
Feb 13 #Javascript
JavaScript实现省市区三级联动
Feb 13 #Javascript
jquery传参及获取方式(两种方式)
Feb 13 #jQuery
You might like
发款php蜘蛛统计插件只要有mysql就可用
2010/10/12 PHP
jQuery EasyUI API 中文文档 - DateBox日期框
2011/10/15 PHP
php生成短域名函数
2015/03/23 PHP
php用正则判断是否为数字的方法
2016/03/25 PHP
php实现常见图片格式的水印和缩略图制作(面向对象)
2016/06/15 PHP
JavaScript For Beginners(转载)
2007/01/05 Javascript
jQuery 源码分析笔记(6) jQuery.data
2011/06/08 Javascript
基于jquery的拖动布局插件
2011/11/25 Javascript
sliderToggle在写jquery的计时器setTimeouter中不生效
2014/05/26 Javascript
setTimeout内不支持jquery的选择器的解决方案
2015/04/28 Javascript
JS 清除字符串数组中,重复元素的实现方法
2016/05/24 Javascript
Vue.js路由组件vue-router使用方法详解
2016/12/02 Javascript
详解nodejs 文本操作模块-fs模块(三)
2016/12/22 NodeJs
Js中async/await的执行顺序详解
2017/09/22 Javascript
深入Node TCP模块的理解
2019/03/13 Javascript
微信小程序非跳转式组件授权登录的方法示例
2019/05/22 Javascript
谈谈IntersectionObserver懒加载的具体使用
2019/10/15 Javascript
vue+AI智能机器人回复功能实现
2020/07/16 Javascript
python监控网卡流量并使用graphite绘图的示例
2014/04/27 Python
Python中使用PyHook监听鼠标和键盘事件实例
2014/07/18 Python
详解TensorFlow在windows上安装与简单示例
2018/03/05 Python
python得到电脑的开机时间方法
2018/10/15 Python
Python 中的参数传递、返回值、浅拷贝、深拷贝
2019/06/25 Python
如何更优雅地写python代码
2019/07/02 Python
python 批量修改 labelImg 生成的xml文件的方法
2019/09/09 Python
Python函数必须先定义,后调用说明(函数调用函数例外)
2020/06/02 Python
python--shutil移动文件到另一个路径的操作
2020/07/13 Python
python中四舍五入的正确打开方式
2021/01/18 Python
css3 border-radius属性详解
2017/07/05 HTML / CSS
详解Canvas事件绑定
2018/06/27 HTML / CSS
《夏夜多美》教学反思
2014/02/17 职场文书
交通事故赔偿协议书
2014/04/15 职场文书
2015年毕业实习工作总结
2015/05/29 职场文书
《百分数的认识》教学反思
2016/02/19 职场文书
担保书怎么写 ?
2019/04/22 职场文书
SQL Server数据库备份和恢复数据库的全过程
2022/06/14 SQL Server