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