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代码
Mar 16 Javascript
jquery 操作DOM案例代码分享
Apr 05 Javascript
javascript错误的认识不用关心内存管理
Dec 15 Javascript
js获取对象为null的解决方法
Nov 21 Javascript
详解jquery中$.ajax方法提交表单
Nov 03 Javascript
js实现背景图自适应窗口大小
Jan 10 Javascript
vue2.0使用Sortable.js实现的拖拽功能示例
Feb 21 Javascript
JS字符串按逗号和回车分隔的方法
Apr 25 Javascript
babel的使用及安装配置教程
Feb 22 Javascript
Angular如何在应用初始化时运行代码详解
Jun 11 Javascript
vue+高德地图实现地图搜索及点击定位操作
Sep 09 Javascript
Javascript confirm多种使用方法解析
Sep 25 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有序表查找之二分查找(折半查找)算法示例
2018/02/09 PHP
javascript TextArea动态显示剩余字符
2008/10/22 Javascript
Jquery Ajax学习实例4 向WebService发出请求,返回实体对象的异步调用
2010/03/16 Javascript
JavaScript的类型转换(字符转数字 数字转字符)
2010/08/30 Javascript
JS获取IP、MAC和主机名的五种方法
2013/11/14 Javascript
javascript中局部变量和全局变量的区别详解
2015/02/27 Javascript
jQuery插件jPaginate实现无刷新分页
2015/05/04 Javascript
JavaScript知识点总结(十)之this关键字
2016/05/31 Javascript
PHP获取当前页面完整URL的方法
2016/12/02 Javascript
ES6 Promise对象概念与用法分析
2017/04/01 Javascript
详解Vue 开发模式下跨域问题
2017/06/06 Javascript
Angular 2父子组件数据传递之@Input和@Output详解 (上)
2017/07/05 Javascript
Vue项目使用CDN优化首屏加载问题
2018/04/01 Javascript
通过cordova将vue项目打包为webapp的方法
2019/02/02 Javascript
Vue多环境代理配置方法思路详解
2019/06/21 Javascript
es6数组之扩展运算符操作实例分析
2020/04/25 Javascript
JavaScript实现单点登录的示例
2020/09/23 Javascript
jquery实现拖拽小方块效果
2020/12/10 jQuery
python脚本实现统计日志文件中的ip访问次数代码分享
2014/08/06 Python
python实现从字符串中找出字符1的位置以及个数的方法
2014/08/25 Python
python常用知识梳理(必看篇)
2017/03/23 Python
简单实现python数独游戏
2018/03/30 Python
Python判断一个list中是否包含另一个list全部元素的方法分析
2018/12/24 Python
python实现Dijkstra静态寻路算法
2019/01/17 Python
python实现串口自动触发工作的示例
2019/07/02 Python
Python实现Selenium自动化Page模式
2019/07/14 Python
使用css3实现超炫的loading加载动画效果
2014/05/07 HTML / CSS
世界上获奖最多的手机镜头:Olloclip
2018/03/03 全球购物
Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型
2013/10/30 面试题
技校个人求职信范文
2014/01/25 职场文书
有关爱国演讲稿
2014/05/07 职场文书
党委班子剖析材料
2014/08/21 职场文书
党在我心中演讲稿
2014/09/02 职场文书
股份合作协议书
2014/09/10 职场文书
2014年党员加强作风建设思想汇报
2014/09/15 职场文书
司机岗位职责范本
2015/04/10 职场文书