- Published on
Husky 進行 pre-commit 發生錯誤
- Authors
- Name
- ChienYu
Table of Contents
Ref
- Husky: https://typicode.github.io/husky/#/?id=command-not-found
- dev-fork-issue-1227: https://github.com/fork-dev/Tracker/issues/1227
- dev-fork-issue-1261: https://github.com/fork-dev/Tracker/issues/1261
錯誤發生情境
在調整 tailwind-nextjs-starter-blog 的過程中, 用 [Fork] (https://git-fork.com/) 工具進行 git commit 的時候遇到以下錯誤, 但用 git 指令一切都正常.
按照錯誤訊息的描述, 是在執行 .husky/pre-commit 這個指令的時候, 讀取該腳本的的第 4 行發生 npx command not found.
.husky/pre-commit: line 4: npx: command not found
husky - pre-commit hook exited with code 127 (error)
先說解法
老實說, 這是我第一次接觸 Husky 就拿著關鍵字亂查了一下. 才知道 Husky 是一個專門處理 git hook 的工具. 而問題發生的原因, 依據 Command-not-found 的描述, npx 沒辦法執行, 有可能是 node 環境發生問題. 推測大概是系統環境變數無法正常被 Fork 工具存取到. 於是我試著按照建議, 另外建立了 ~/.huskyrc 確實解決了我的問題.
# ~/.huskyrc
# This loads nvm.sh and sets the correct PATH before running hook
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
上面的腳本大概解釋如下
- 第一部分
-s "$NVM_DIR/nvm.sh"會檢查$NVM_DIR目錄下的 nvm.sh 檔案是否存在. - 第二部分
&& \. "$NVM_DIR/nvm.sh中的 && 是一個邏輯運算符,它表示當第一部分條件成立時才會執行第二部分.\.會執行 nvm.sh 檔案中的程式碼, 這是一個 Shell Script.
Why
事實上, 我確定我有上面的相關設定, 我是用 NVM 管理我的 Node 版本沒錯. 依據 NVM 的教學, 我在 ~/.bash_profile 裡面有了這段設定.
# nvm
export NVM_DIR="$HOME/.nvm"
. "/usr/local/opt/nvm/nvm.sh"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads
我另外分別於 ~/.bash_profile 與 ~/.zshrc 加入 echo 確認過載入順序是
- ~/.zshrc
- ~/.bash_profile
於是我實驗性地把這段重新搬到 ~/.zshrc, 再重新將 ~/.zshrc 載入到 session 中, 仍然是可以在 terminal 上執行 git commit 但仍無法在 Fork 上 commit.
fork-dev Issue 1227
在這個討論串內, 確實有提到 Fork 不支援使用者的環境變數. Fork 主要是驅動環境的 git 去做 git hook 相關作業. 所以沒辦法執行 husky 確實不是 Fork 的問題. 但這個討論也讓我更確定是因為 Fork 沒有載入到 NPM 的相關環境變數, 主因是用了 NVM 管理 NPM. 然而我沒辦法在 Fork 上確認這件事 XD.
# 確認 npm 位置
which npm
# 我的 npm 路徑
/Users/user_name/.nvm/versions/node/v18.12.1/bin/npm
fork-dev Issue 1261
然而在這個討論串內, 提到用指令打開 Fork open -a Fork, 會讓 Fork 繼承 Parent process, 也就是會繼承下這個指令時的環境變數. 在這個階段下打開 Fork 又可以 commit 了.
但我自己的習慣都是用 Mac Spotlight 來開啟相關工具, 所以按照討論串的建議, 在 ~/.husky/pre-commit 檔案內, 加入 echo $PATH, 展開來就是這樣, 間接的確認到 Fork 的環境變數了.
/usr/local/Cellar/git/2.32.0/libexec/git-core
/Applications/Fork.app/Contents/Resources/git-instance/git-lfs
/Applications/Fork.app/Contents/Resources/gitflow-avh
/opt/homebrew/bin
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
裡面當然沒有 NVM 的 NPM 相關環境變數 XD, 也沒有 ~/.zshrc 與 ~/.bash_profile.
總結
解法 1
採用 ~/.huskyrc 作法
# ~/.huskyrc
# This loads nvm.sh and sets the correct PATH before running hook
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
解法 2
用 terminal 打開 Fork, open -a Fork.
解法 3
把當下的 node 相關指令, 用建立捷徑的方式 (symbolic link), 把 node 相關的 bin 連結到 /usr/local/bin
ln -s $(which node) /usr/local/bin/node