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 相关文章推荐
获取焦点时,利用js定时器设定时间执行动作
Apr 02 Javascript
10个实用的脚本代码工具
May 04 Javascript
js 浏览器事件介绍
Mar 30 Javascript
extjs 分页使用jsp传递数据示例
Jul 29 Javascript
JS获取当前脚本文件的绝对路径
Mar 02 Javascript
用JS动态设置CSS样式常见方法小结(推荐)
Nov 10 Javascript
JavaScript 输出显示内容(document.write、alert、innerHTML、console.log)
Dec 14 Javascript
详解.vue文件解析的实现
Jun 11 Javascript
详解超简单的react服务器渲染(ssr)入坑指南
Feb 28 Javascript
原生js实现each方法实例代码详解
May 27 Javascript
vue结合el-upload实现腾讯云视频上传功能
Jul 01 Javascript
微信小程序实现滚动Tab选项卡
Nov 16 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中copy on write写时复制机制介绍
2014/05/13 PHP
PHP使用redis实现统计缓存mysql压力的方法
2015/11/14 PHP
php简单实现sql防注入的方法
2016/04/22 PHP
Laravel 模型关联基础教程详解
2019/09/17 PHP
Laravel框架实现文件上传的方法分析
2019/09/29 PHP
Laravel 实现关系模型取出需要的字段
2019/10/10 PHP
javascript 浏览器判断 绑定事件 arguments 转换数组 数组遍历
2009/07/06 Javascript
namespace.js Javascript的命名空间库
2011/10/11 Javascript
jquery中的ajax方法怎样通过JSONP进行远程调用
2014/05/04 Javascript
让javascript加载速度倍增的方法(解决JS加载速度慢的问题)
2014/12/12 Javascript
利用JavaScript的AngularJS库制作电子名片的方法
2015/06/18 Javascript
jQuery实现百度登录框的动态切换效果
2017/04/21 jQuery
vue-cli项目中使用公用的提示弹层tips或加载loading组件实例详解
2018/05/28 Javascript
vue3.0 CLI - 2.5 - 了解组件的三维
2018/09/14 Javascript
详解jQuery设置内容和属性
2019/04/11 jQuery
微信小程序页面渲染实现方法
2019/11/06 Javascript
JavaScript写个贪吃蛇小游戏(超详细)
2020/03/17 Javascript
在Vue 中获取下拉框的文本及选项值操作
2020/08/13 Javascript
详解python中的json和字典dict
2018/06/22 Python
Flask框架使用DBUtils模块连接数据库操作示例
2018/07/20 Python
python TKinter获取文本框内容的方法
2018/10/11 Python
python使用gdal对shp读取,新建和更新的实例
2020/03/10 Python
解决Keras中CNN输入维度报错问题
2020/06/29 Python
Html5 video标签视频的最佳实践
2020/02/26 HTML / CSS
Html5移动端div固定到底部实现底部导航条的几种方式
2021/03/09 HTML / CSS
通息工程毕业生自荐信
2013/10/16 职场文书
应届生学校辅导员求职信
2013/11/07 职场文书
上班打牌检讨书
2014/02/07 职场文书
创建学习型党组织实施方案
2014/03/29 职场文书
租房协议书样本
2014/08/20 职场文书
中职三好学生事迹材料
2014/08/24 职场文书
党的群众路线教育实践活动对照检查材料(教师)
2014/09/24 职场文书
2019年汽车租赁合同范本!
2019/08/12 职场文书
导游词之贵州百里杜鹃
2019/10/29 职场文书
Python turtle实现贪吃蛇游戏
2021/06/18 Python
Vue3中的Refs和Ref详情
2021/11/11 Vue.js