摘要:例如提供的用于修改的鉤子就需要在的同時從遠(yuǎn)程服務(wù)器下載到本地來替換,代碼如下這當(dāng)然是一種好方式。安裝簡單到看完配置就懂了吧,直接在中增加這一項,并直接把想執(zhí)行的語句寫在里面即可。
在前端的日常工作中,經(jīng)常會出現(xiàn)“當(dāng)執(zhí)行一種操作之前(之后)需要同時執(zhí)行另一種操作”的情況,比如我們希望在每次git commit之前都運行eslint代碼檢查、npm install之前檢查項目依賴等。作為經(jīng)典的情況,各類工具都可以讓我們在特定的動作發(fā)生時觸發(fā)自定義腳本,這個功能就叫鉤子hooks。
日常經(jīng)常用到的工具有npm、git、webpack,其中的hooks用法我們分別介紹一下。
其中webpack的hooks是webpack為開發(fā)者提供的運行時事件鉤子,我們能利用它來編寫plugins,這個就不在這里說了,將來會多帶帶寫一篇關(guān)于寫plugin的文章(立個flag╮(╯▽╰)╭)。
npm hooks —— 監(jiān)聽npm操作 / 訂閱npm源修改獲取通知目前提到npm hooks,有兩個不同概念的操作。
通常意義下的監(jiān)聽npm各類操作的鉤子是通過配置package.json文件中的scripts字段來實現(xiàn)的。
而npm hooks則是npm提供的命令行操作,目的是為了訂閱你需要的npm package發(fā)生的特定改動,比如可以訂閱尤大(誤)的新動態(tài)等。當(dāng)然,這項功能需要你自己提供一個域名,并且需要有npm賬號且購買服務(wù),所以就不多討論了╮(╯▽╰)╭,具體參見npm-hook官方文檔。
npm script hooks使用方法很簡單,在項目的package.json中的scripts字段加入"hook": "script"鍵值對即可。hook名稱由npm提供,script就是能夠運行的shell語句。下面列幾個常用的hook:
preinstall: 在npm install之前執(zhí)行
install, postinstall: 在npm install之后執(zhí)行
prestart: 在npm start之前執(zhí)行
start, poststart: 在npm start之后執(zhí)行
etc.
從以上的例子中可以看出,hooks的命名是pre[op]為操作之前的鉤子,[op]或post[op]為操作之后的鉤子。還有很多其他的鉤子,具體可以查閱npm script官方文檔。
由于歷史原因,publish相關(guān)的鉤子會比較特殊,具體原因和修改后的樣子都在文檔里了,不多介紹。
比如項目npm install之前依賴一個全局的npm包,用戶需要先npm install -g package,這時就可以把該操作寫到preinstall里:
package.json
... "scripts": { "preinstall": "npm install -g package" ... },
當(dāng)然,shell的部分可以寫所有的可以執(zhí)行的shell語句。如果需要的操作比較多,也可以寫shell腳本,然后執(zhí)行該腳本。對很多前端來說,直接開搞shell腳本比較困難,也可以寫node、python等腳本,然后用node script.js的方式執(zhí)行也是ok的。
git hooks —— 監(jiān)聽git操作 介紹git hooks基本跟上面介紹的npm script hooks差不多,也是配置相應(yīng)的pre-[op]、post-[op]之類的鉤子。
git通過項目根目錄下的.git目錄中的內(nèi)容來標(biāo)記一個git庫并記錄相關(guān)信息,這點應(yīng)該是眾所周知了。
git hooks的配置就在.git/hooks目錄下,以無后綴的腳本文件的形式存在,文件名稱即是鉤子名稱,文件內(nèi)容是shell腳本,你可以自行添加可執(zhí)行內(nèi)容。一般在剛npm init的hooks文件夾中全都是[hook].sample示例文件,需要復(fù)制并改名為該hook名稱才可以正常使用。
根據(jù)git版本不同,可用的hooks也不同,舉下跟commit相關(guān)的hook例子:
pre-commit: 在commit之前運行
post-commit: 在commit之后運行
prepare-commit-msg: 在啟動提交信息編輯器之前(git commit -s那個),默認(rèn)信息被創(chuàng)建之后運行
commit-msg: 生成基本commit-msg時觸發(fā),可以用來在提交通過前驗證項目狀態(tài)或提交信息
還有很多基于其他操作的鉤子,都因工作流程不同而有所不同,具體可以查閱Git 鉤子官方文檔。
**鉤子腳本可以按照指責(zé)不同接收不同的參數(shù)并進(jìn)行修改。**比如commit-msg鉤子,鉤子接收一個參數(shù),是存有當(dāng)前提交信息的臨時文件的路徑,參數(shù)可以在shell腳本中以$1的形式進(jìn)行調(diào)用,有了這個我們就可以修改文件中的提交信息了。
舉個例子,當(dāng)你想在每次commit之前用檢查代碼規(guī)范與否,就可以直接在pre-commit腳本最后添加npm run lint(這里看自己相關(guān)配置,不一定是這句)。
但是,git hooks的設(shè)計思路是在每臺終端以及服務(wù)器端提供不同的定制方案。說人話,就是因為git是一種分布式的系統(tǒng),它保證了所有終端的版本都是相同的,但hooks在服務(wù)器端和私人終端的配置可能不一樣,所以hooks的配置不能跟隨git提交。
例如gerrit提供的用于修改commit message的commit-msg鉤子就需要在git clone的同時從遠(yuǎn)程服務(wù)器下載到本地來替換,代碼如下:
git clone ssh://[email protected]:29418/All-Projects && scp -p -P 29418 [email protected]:hooks/commit-msg All-Projects/.git/hooks/
這當(dāng)然是一種好方式。但有一種情況,當(dāng)我們沒有其他的可以存儲腳本的第三方服務(wù)器,又希望將hooks同步給所有終端,該怎么辦呢?
用更簡單的方式使用git hooks為了解決上面的問題,有很多大神寫了第三方工具來實現(xiàn)hooks同步。對于前端來說,可以在npm安裝的第三方工具有很多,例如husky、yorky、git-hooks等。yorkie是Vue作者尤雨溪fork了husky并做了一些修改的工具,改善了一些使用體驗,所這里我們介紹一下yorkie。
*注:git-hooks跟前兩種工具的思路不同,感興趣可以了解一下:git-hooks。
$ npm install yorkie --save-dev
// package.json { "gitHooks": { "pre-commit": "npm test", "commit-msg": "npm test", "...": "..." } }
簡單到看完配置就懂了吧,直接在package.json中增加gitHooks這一項,并直接把想執(zhí)行的shell語句寫在里面即可。
在安裝過yorkie之后,比對一下安裝之前的hook文件,會發(fā)現(xiàn)yorkie直接重寫了所有的hooks。所以我們把/.git/hooks/pre-commit的核心代碼貼出來看看yorkie做了什么:
has_hook_script () {
[ -f package.json ] && cat package.json | grep -q ""$1"[[:space:]]*:"
}
cd "."
# Check if pre-commit is defined, skip if not
has_hook_script pre-commit || exit 0
# Add common path where Node can be found
# Brew standard installation path /usr/local/bin
# Node standard installation path /usr/local
export PATH="$PATH:/usr/local/bin:/usr/local"
# Export Git hook params
export GIT_PARAMS="$*"
# Run hook
node "./node_modules/yorkie/src/runner.js" pre-commit || {
echo
echo "pre-commit hook failed (add --no-verify to bypass)"
exit 1
}
忽略上面那些檢查是否存在hook腳本的代碼,最后執(zhí)行了node ./node_modules/yorkie/src/runner.js:
const fs = require("fs")
const path = require("path")
const execa = require("execa")
const cwd = process.cwd()
const pkg = fs.readFileSync(path.join(cwd, "package.json"))
const hooks = JSON.parse(pkg).gitHooks // 將package.json重的hooks字段取出來
if (!hooks) { // 沒有hook則退出
process.exit(0)
}
const hook = process.argv[2] // 這里的process.argv[2]就是在hooks腳本里傳過來的hook名稱,如pre-commit
const command = hooks[hook]
if (!command) { // 不是當(dāng)前hook則退出
process.exit(0)
}
console.log(` > running ${hook} hook: ${command}`)
try {
execa.shellSync(command, { stdio: "inherit" }) // 使用execa.shellSync運行命令
} catch (e) {
process.exit(1)
}
關(guān)于對runner.js的解析,我寫到了注釋中,應(yīng)該都能看得懂。即通過(npm install時改寫hooks --> 將hooks改為運行自己的runner --> runner依賴package.json)的方式,實現(xiàn)了將hooks信息保存在package.json中并可以通過git共享給所有項目成員。
END俗話說,懶惰是人類進(jìn)步的動力,希望可以用這些東西,做到一鍵完成所有手工重復(fù)任務(wù),提高我們的工作效率,把時間用在更有意義的事情上。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/7206.html
摘要:顧名思義,受控組件的值由控制,能為與用戶交互的元素提供值,而不受控制的元素不獲取值屬性。另外我發(fā)現(xiàn)受控組件更容易理解和于使用。只是一種把組件作為參數(shù)的函數(shù),并且與沒有包裝器的組件相比,能夠返回具有擴(kuò)展功能的新組件。其中三個基本的是,和。 翻譯:瘋狂的技術(shù)宅原文:https://www.toptal.com/react/... 本文首發(fā)微信公眾號:jingchengyideng歡迎關(guān)...
摘要:當(dāng)退出的錯誤碼不為的時候,表示失敗,操作終止,否則操作繼續(xù)。執(zhí)行命令進(jìn)行測試,如果測試全部通過的話,退出,錯誤碼為,否則錯誤碼為,同樣退出。這樣雖然沒有解決不會隨著倉庫移動的問題,但也提供了一種在項目組里通用一套的方案。 git hooks想必很多攻城獅都不陌生,官方對于hooks有詳細(xì)的文檔,也有站內(nèi)網(wǎng)友的文章Git Hooks (1):介紹,GIt Hooks (2):腳本分類,說...
摘要:月日,第六屆大會在深圳召開。這是這次大會的第二站活動,第一站已在上海成功舉辦。深圳站視頻及,請在公眾號后臺回復(fù),獲取分享鏈接。據(jù)介紹,目前支持多種開發(fā)庫,如內(nèi)置和等。該協(xié)議的推出,是為了統(tǒng)一標(biāo)準(zhǔn),提高效率。 本文為 PyChina 和「編程派」聯(lián)合首發(fā),作者為 EarlGrey。「編程派」是一個專注 Python 學(xué)習(xí)交流的微信公眾號。 9 月 25 日,第六屆 PyCon China...
摘要:目前埋點分為兩種方式,有碼與無碼埋點。本文主要介紹無碼埋點的技術(shù)實現(xiàn)。無碼埋點的實現(xiàn)流程可視化視圖圈選,在頁面上會出現(xiàn)浮動的圓圈,拖動圓圈至想配置事件的控件上,將會彈出輸入事件的彈框。 showImg(https://segmentfault.com/img/bVXMSS?w=900&h=500);隨著大數(shù)據(jù)時代的到來,數(shù)據(jù)采集也已經(jīng)變的越來越重要。前端埋點作為一個比較成熟的數(shù)據(jù)接入手...
閱讀 3018·2021-11-23 09:51
閱讀 3622·2021-10-13 09:39
閱讀 2507·2021-09-22 15:06
閱讀 889·2019-08-30 15:55
閱讀 3159·2019-08-30 15:44
閱讀 1791·2019-08-30 14:05
閱讀 3447·2019-08-29 15:24
閱讀 2372·2019-08-29 12:44