[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"navigation":3,"page-\u002Fblog\u002Ftech\u002Fhusky-git-hooks":147,"searchResults":724},[4],{"title":5,"path":6,"stem":7,"children":8,"description":146,"publishedAt":15,"tags":15,"image":15,"score":15,"draft":16},"Blog","\u002Fblog","blog",[9,30,44,68,112,136],{"title":10,"path":11,"stem":12,"children":13,"description":15,"publishedAt":15,"tags":15,"image":15,"score":15,"draft":16,"head":17},"最新文章","\u002Fblog\u002Fnews","blog\u002F0.news\u002F0.index",[14],{"title":10,"path":11,"stem":12,"description":15,"publishedAt":15,"tags":15,"image":15,"score":15,"draft":16},null,false,{"meta":18},[19,21,24,27],{"name":20,"content":10},"keywords",{"name":22,"content":23},"robots","index, follow",{"name":25,"content":26},"author","Annie",{"name":28,"content":29},"copyright","© 2024 RinTree",{"title":31,"path":32,"stem":33,"children":34,"description":15,"publishedAt":15,"tags":15,"image":15,"score":15,"draft":16,"head":37},"影劇推薦","\u002Fblog\u002Fdrama","blog\u002F2.drama\u002F0.index",[35],{"title":31,"path":32,"stem":33,"description":36,"publishedAt":15,"tags":15,"image":15,"score":15,"draft":16},"推薦您 Netflix 和 Disney+ 影劇小編愛好的好評清單。",{"meta":38},[39,40,41,43],{"name":20,"content":31},{"name":22,"content":23},{"name":25,"content":42},"爆米花鼠",{"name":28,"content":29},{"title":45,"path":46,"stem":47,"children":48,"description":15,"publishedAt":15,"tags":15,"image":15,"score":15,"draft":16,"head":61},"書籍分享","\u002Fblog\u002Fbook","blog\u002F3.book\u002F0.index",[49,51],{"title":45,"path":46,"stem":47,"description":50,"publishedAt":15,"tags":15,"image":15,"score":15,"draft":16},"推薦您好書與全台圖書館的免費可借閱電子書情報！",{"title":52,"path":53,"stem":54,"description":55,"publishedAt":56,"tags":57,"image":58,"score":15,"draft":16},"HyRead 電子書｜書籍推薦｜《不便利的便利店》暖心人生故事 推薦指數⭐⭐⭐⭐","\u002Fblog\u002Fbook\u002Fconvenience-store","blog\u002F3.book\u002F3.convenience-store","《不便利的便利店》以一家便利店為故事核心，是韓國年度最受歡迎的小說之一，銷量突破 70 萬冊，並獲選為 25 個城市的年度推薦好書。由金浩然著，目前已出版兩冊：《不便利的便利店》與《不便利的便利店 2》。","2025-01-17","HyRead，電子書，書籍推薦",{"src":59,"alt":60},"\u002Fcover\u002Fconvenience-store.png","HyRead 電子書 不便利的便利店",{"meta":62},[63,65,66,67],{"name":20,"content":64},"書籍，電子書",{"name":22,"content":23},{"name":25,"content":26},{"name":28,"content":29},{"title":69,"path":70,"stem":71,"children":72,"description":15,"publishedAt":15,"tags":15,"image":15,"score":15,"draft":16,"head":106},"科技生活","\u002Fblog\u002Ftech","blog\u002F4.tech\u002F0.index",[73,76,86,96],{"title":74,"path":70,"stem":71,"description":75,"publishedAt":15,"tags":15,"image":15,"score":15,"draft":16},"數位開發盒","關於程式開發、網路架站、SEO 等數位工具與心得的分享。",{"title":77,"path":78,"stem":79,"description":80,"publishedAt":81,"tags":82,"image":83,"score":15,"draft":16},"ESLint 工程師必備外掛：第一道程式碼品質檢測，一鍵清理舊程式碼，如何安裝與設定","\u002Fblog\u002Ftech\u002Feslint-first-line-of-defense","blog\u002F4.tech\u002F2.eslint-first-line-of-defense","探討 AI 開發時代為什麼更需要 ESLint，以及如何設定 ESLint 來作為程式碼品質的第一道防線。","2026-08-16","ESLint，AI，程式開發，Code Review，外掛插件",{"src":84,"alt":85},"\u002Fcover\u002Feslint.jpg","AI 寫 Code 忘記清理舊程式嗎？用 ESLint 築起專案第一道護欄，抓出潛在的程式碼地雷",{"title":87,"path":88,"stem":89,"description":90,"publishedAt":91,"tags":92,"image":93,"score":15,"draft":16},"ESLint 安全外掛 eslint-plugin-security：為 Node.js 專案進行資安檢查，攔截潛在漏洞","\u002Fblog\u002Ftech\u002Feslint-plugin-security","blog\u002F4.tech\u002F3.eslint-plugin-security","介紹如何為專案加入 eslint-plugin-security，在程式碼靜態檢查中築起安全性護欄，自動揪出 ReDoS、物件注入與危險調用等潛在資安漏洞。","2026-09-24","ESLint，Node.js，資安防護，靜態分析，外掛插件",{"src":94,"alt":95},"\u002Fcover\u002Feslint-plugin-security.jpg","ESLint 進階安全外掛 eslint-plugin-security：為專案築起資安防護網",{"title":97,"path":98,"stem":99,"description":100,"publishedAt":101,"tags":102,"image":103,"score":15,"draft":16},"Git Hooks 自動化守門員 Husky：在 Commit 與 Push 前執行檢查腳本","\u002Fblog\u002Ftech\u002Fhusky-git-hooks","blog\u002F4.tech\u002F4.husky-git-hooks","介紹如何運用 Husky 搭配 Git Hooks，在程式碼 Commit 與 Push 階段自動化執行 ESLint、測試 與各種自訂檢查腳本，只要三分鐘就能設定完成，再也不用擔心忘記執行檢查。","2026-09-30","Husky，外掛插件，專案工程，程式碼品質",{"src":104,"alt":105},"\u002Fcover\u002Fhusky.jpg","告別手動執行！Husky 幫專案築起 Git 推送守衛牆",{"meta":107},[108,110,111],{"name":20,"content":109},"科技，生活",{"name":22,"content":23},{"name":28,"content":29},{"title":113,"path":114,"stem":115,"children":116,"description":15,"publishedAt":15,"tags":15,"image":15,"score":15,"draft":16,"head":130},"梨子製造所","\u002Fblog\u002Ftools","blog\u002F5.tools\u002F0.index",[117,120],{"title":118,"path":114,"stem":115,"description":119,"publishedAt":15,"tags":15,"image":15,"score":15,"draft":16},"數位工具箱","好用的精選資源，線上網站與 手機 APP 等分享。",{"title":121,"path":122,"stem":123,"description":124,"publishedAt":125,"tags":126,"image":127,"score":15,"draft":16},"手機 One UI 6 更新！ 新增螢幕搜索功能：圖像和文字搜尋太棒了！","\u002Fblog\u002Ftools\u002Fone-ui-search","blog\u002F5.tools\u002F1.one-ui-search","最近，我的 Samsung 手機剛剛才升級到了 One UI 6.1，其中一個讓我驚喜的新功能就是螢幕搜尋圈 (Circle to Search with Google) 。這個功能讓我們可以更加輕鬆地在手機上搜尋圖片和文字。今天，我將帶大家一起探索這個實用的功能，並教大家如何使用它。","2024-03-18","安卓 Android，三星 Samsung，手機操作",{"src":128,"alt":129},"\u002Fimg\u002Fcontent\u002Fsamsung-one-ui-circle-to-search-overview.jpg","Samsung One UI 圈選搜尋 (Circle to Search)",{"meta":131},[132,134,135],{"name":20,"content":133},"開發，製造",{"name":22,"content":23},{"name":28,"content":29},{"title":113,"path":137,"stem":138,"children":139,"description":15,"publishedAt":15,"tags":15,"image":15,"score":15,"draft":16,"head":141},"\u002Fblog\u002Fcreator","blog\u002F6.creator\u002F0.index",[140],{"title":69,"path":137,"stem":138,"description":15,"publishedAt":15,"tags":15,"image":15,"score":15,"draft":16},{"meta":142},[143,144,145],{"name":20,"content":133},{"name":22,"content":23},{"name":28,"content":29},"Read the latest news about Nuxt Content or articles about the Studio platform.",{"page":148,"surround":717},{"id":149,"title":97,"author":150,"body":151,"description":100,"draft":16,"extension":712,"image":713,"meta":714,"navigation":518,"path":98,"publishedAt":101,"score":15,"seo":715,"stem":99,"tags":102,"updated":101,"__hash__":716},"blog\u002Fblog\u002F4.tech\u002F4.husky-git-hooks.md","梨子",{"type":152,"value":153,"toc":702},"minimark",[154,173,176,181,188,191,199,202,207,217,226,252,258,265,268,313,320,322,326,329,334,339,367,390,393,397,413,418,453,456,460,467,476,484,491,536,552,566,573,582,600,629,635,637,641,648,654,684,686,689,698],[155,156,157,164],"desc",{},[158,159,160],"p",{},[161,162],"binding",{"value":163},"description",[158,165,166,167,172],{},"想要探索更多高效率前端與工程化工具？歡迎瀏覽 ",[168,169,171],"a",{"href":70,"target":170},"_blank","本站技術專區"," 獲取最新實戰技巧！",[174,175],"toc",{},[177,178],"rest",{"icon":179,"label":180},"ph:shield-check-duotone","START",[158,182,183,184,187],{},"上一篇介紹了用 ESLint 做程式碼檢查，但 ESLint 終究是靠手動執行，難免會有遺忘的時候，團隊裡的新手也可能在不知情的情況下漏掉這個步驟。\n（延伸閱讀：",[168,185,186],{"href":78,"target":170},"用 ESLint 築起專案第一道護欄，抓出潛在的程式碼地雷 ｜ 套件推薦 01","）",[158,189,190],{},"隨著專案越來越大，上線與提交前要跑的檢查指令只會越來越多。在頻繁修改與趕進度的情況下，難免會忘記執行；又或者新加入的團隊成員根本不知道有這套檢查流程，等到代碼都推上去甚至部署了，才發現漏掉了好幾項檢查。",[158,192,193,194,198],{},"今天來介紹一款 ",[195,196,197],"strong",{},"Husky"," 套件，它可以用來管理 Git Hooks。把這整串檢查流程變成「自動化守門員」，讓 Git 在你 commit 或 push 之前先強制跑一遍，不用再靠人腦記憶要做的步驟，徹底杜絕漏跑的風險！",[200,201],"hr",{},[203,204,206],"h2",{"id":205},"husky-是什麼","Husky 是什麼？",[208,209],"resource-card",{"description":210,"forks":211,"icon":212,"license":213,"stars":214,"title":215,"url":216},"現代化 Git Hooks 自動化管理工具，把關每次 Commit 與 Push 的品質守門員。","1.1k","ri:github-fill","MIT","35.3k","husky","https:\u002F\u002Fgithub.com\u002Ftypicode\u002Fhusky",[158,218,219,221,222,225],{},[195,220,197],{}," 是一個管理 Git Hooks 的工具。Git 本身內建一個機制叫做 ",[195,223,224],{},"Git Hooks","，簡單說就是「在你執行某個 Git 指令的時候，自動夾帶跑一段腳本」。",[227,228,230,237],"callout",{"type":229},"left",[231,232,234],"template",{"v-slot:title":233},"",[158,235,236],{},"什麼是 Git Hooks？",[158,238,239,240,244,245,244,248,251],{},"Git 本身內建的一種事件掛鉤機制。當你在終端機執行特定 Git 操作（如 ",[241,242,243],"code",{},"commit","、",[241,246,247],{},"push",[241,249,250],{},"merge","）時，系統會自動在前後特定的生命週期點觸發對應的自訂腳本。",[158,253,254,255],{},"你可以把它想成是路障：",[195,256,257],{},"Git 要往前走之前，先讓你的腳本檢查一遍，通過了才放行。",[158,259,260],{},[261,262],"img",{"alt":263,"src":264},"Husky 運作示意圖 : 忘記執行指令？讓 Husky 幫你自動化守門","\u002Fimg\u002Fcontent\u002Fhusky-git-hooks-husky-husky.webp",[158,266,267],{},"常見的 hook 有三種守門時機：",[269,270,271,285,297],"ul",{},[272,273,274,280,281,284],"li",{},[195,275,276,279],{},[241,277,278],{},"pre-commit","（存檔前檢查）","：在 ",[241,282,283],{},"git commit"," 之前觸發。在程式碼存入本地版本紀錄前先做第一道基本檢查（如語法或格式）。",[272,286,287,280,293,296],{},[195,288,289,292],{},[241,290,291],{},"pre-push","（推送前把關）",[241,294,295],{},"git push"," 之前觸發。在程式碼推送到遠端伺服器（例如 GitHub）前做最後的大關卡檢驗（如資安稽核或測試）。",[272,298,299,305,306,244,309,312],{},[195,300,301,304],{},[241,302,303],{},"commit-msg","（訊息格式檢查）","：在輸入 commit 訊息後觸發。通常用來檢查提交訊息是否符合團隊規範（例如 ",[241,307,308],{},"feat:",[241,310,311],{},"fix:","）。",[158,314,315,316,319],{},"這些 hook 腳本原本要自己去 ",[241,317,318],{},".git\u002Fhooks\u002F"," 資料夾手動建立，而且不會被 Git 追蹤，換一台電腦就要重設。Husky 解決了這個問題，讓你把 hook 設定放進專案裡，所有人 clone 下來就能用。",[200,321],{},[203,323,325],{"id":324},"如何在專案中設定-husky","如何在專案中設定 Husky？",[158,327,328],{},"設定非常輕量，短短三分鐘內就能完成建置。",[330,331],"u-button",{"label":332,"type":333},"STEP 1","step",[335,336,338],"h3",{"id":337},"_1-安裝-husky","1. 安裝 Husky",[340,341,345],"pre",{"className":342,"code":343,"language":344,"meta":233,"style":233},"language-bash shiki shiki-themes ayu-dark","npm install --save-dev husky\n","bash",[241,346,347],{"__ignoreMap":233},[348,349,352,356,360,364],"span",{"class":350,"line":351},"line",1,[348,353,355],{"class":354},"sP_rH","npm",[348,357,359],{"class":358},"skAsU"," install",[348,361,363],{"class":362},"sHCZS"," --save-dev",[348,365,366],{"class":358}," husky\n",[158,368,369,370,373,374,377,378,381,382,385,386,389],{},"➜ ",[195,371,372],{},"執行後的效果","：",[241,375,376],{},"package.json"," 的 ",[241,379,380],{},"devDependencies"," 裡會出現 husky 的版本號（例如 ",[241,383,384],{},"\"husky\": \"^9.1.7\"","），同時 ",[241,387,388],{},"node_modules\u002Fhusky\u002F"," 資料夾也會出現在專案裡。",[330,391],{"label":392,"type":333},"STEP 2",[335,394,396],{"id":395},"_2-初始化-husky","2. 初始化 Husky",[340,398,400],{"className":342,"code":399,"language":344,"meta":233,"style":233},"npx husky init\n",[241,401,402],{"__ignoreMap":233},[348,403,404,407,410],{"class":350,"line":351},[348,405,406],{"class":354},"npx",[348,408,409],{"class":358}," husky",[348,411,412],{"class":358}," init\n",[158,414,369,415,417],{},[195,416,372],{},"：專案根目錄會自動產生以下變化：",[269,419,420,433],{},[272,421,422,423,426,427,429,430,432],{},"新增 ",[241,424,425],{},".husky\u002F"," 資料夾，並在 ",[241,428,425],{}," 裡建立一個預設的 ",[241,431,278],{}," 範例檔案。",[272,434,435,377,437,440,441,444,445,448,449,452],{},[241,436,376],{},[241,438,439],{},"scripts"," 自動加入 ",[241,442,443],{},"\"prepare\": \"husky\"","，這個腳本的作用是：任何人 ",[241,446,447],{},"npm install"," 之後，Husky 會自動初始化，不用再手動執行一次 ",[241,450,451],{},"npx husky init","。",[330,454],{"label":455,"type":333},"STEP 3",[335,457,459],{"id":458},"_3-設定-hook-指令請依需求設定","3. 設定 Hook 指令（請依需求設定）",[158,461,462,463,466],{},"Hook 檔案本質上就是標準的 Shell 腳本，",[195,464,465],{},"裡面的檢查指令完全可以根據專案需求自由自訂","（任何你在終端機能執行的 npm 腳本或 bash 指令都能放進去）。",[468,469,470],"blockquote",{},[158,471,472,473],{},"💡 ",[195,474,475],{},"以下為小編的設定範例，你可以自由設定！",[477,478,480,481,483],"h4",{"id":479},"在-pre-commit本地提交前","① 在 ",[241,482,278],{},"（本地提交前）",[158,485,486,487,490],{},"打開自動產生的 ",[241,488,489],{},".husky\u002Fpre-commit","，你可以寫入想在 commit 前自動執行的指令，例如：執行輕量的語法檢查與單元測試，確保程式品質且功能正常：",[340,492,494],{"className":342,"code":493,"language":344,"meta":233,"style":233},"# 1. 執行 ESLint 語法檢查\nnpm run lint\n\n# 2. 執行單元測試（可依專案腳本調整，如 npm test）\nnpm run test:unit\n",[241,495,496,502,513,520,526],{"__ignoreMap":233},[348,497,498],{"class":350,"line":351},[348,499,501],{"class":500},"sOSKZ","# 1. 執行 ESLint 語法檢查\n",[348,503,505,507,510],{"class":350,"line":504},2,[348,506,355],{"class":354},[348,508,509],{"class":358}," run",[348,511,512],{"class":358}," lint\n",[348,514,516],{"class":350,"line":515},3,[348,517,519],{"emptyLinePlaceholder":518},true,"\n",[348,521,523],{"class":350,"line":522},4,[348,524,525],{"class":500},"# 2. 執行單元測試（可依專案腳本調整，如 npm test）\n",[348,527,529,531,533],{"class":350,"line":528},5,[348,530,355],{"class":354},[348,532,509],{"class":358},[348,534,535],{"class":358}," test:unit\n",[269,537,538,544],{},[272,539,540,543],{},[195,541,542],{},"指令說明","：在 commit 之前先跑全專案的 ESLint 語法檢查與測試，只要任一項出錯就會自動阻擋 commit，避免有瑕疵的代碼進入版本控制。",[272,545,546,548,549,551],{},[195,547,372],{},"：下次執行 ",[241,550,283],{}," 時，終端機會依序執行這些指令，全數通過後才會順利完成提交。",[227,553,556],{"type":554,"title":555},"warning","注意事項：注意既有專案的歷史報錯",[158,557,558,559,561,562,565],{},"若在 ",[241,560,278],{}," 設定了 ",[241,563,564],{},"npm run lint","，建議先確認專案已經完整跑過 ESLint 並修復現存問題。如果既有專案本來就累積了大量歷史 lint 報錯，開啟後第一次 commit 會全部被攔截，需要先做一次性的清理。",[477,567,569,570,572],{"id":568},"在-pre-push遠端推送前","② 在 ",[241,571,291],{},"（遠端推送前）",[158,574,575,576,578,579,581],{},"在 ",[241,577,425],{}," 資料夾裡新增一個名為 ",[241,580,291],{}," 的檔案，你可以寫入想在 push 前自動執行的指令，例如：執行嚴格的資安稽核檢查：",[340,583,585],{"className":342,"code":584,"language":344,"meta":233,"style":233},"npm audit --audit-level=high --omit=dev\n",[241,586,587],{"__ignoreMap":233},[348,588,589,591,594,597],{"class":350,"line":351},[348,590,355],{"class":354},[348,592,593],{"class":358}," audit",[348,595,596],{"class":362}," --audit-level=high",[348,598,599],{"class":362}," --omit=dev\n",[269,601,602,610,618],{},[272,603,604,609],{},[195,605,606],{},[241,607,608],{},"--audit-level=high","：只有「高風險」以上的漏洞才會阻擋 push，避免低風險雜訊干擾開發。",[272,611,612,617],{},[195,613,614],{},[241,615,616],{},"--omit=dev","：只檢查 production 依賴，開發工具的漏洞不算在內。",[272,619,620,548,622,624,625,628],{},[195,621,372],{},[241,623,295],{}," 時，終端機會先出現 ",[241,626,627],{},"npm audit"," 的掃描結果。如果沒有漏洞，push 正常繼續；如果有高風險漏洞，push 會被阻擋並列出問題清單。",[158,630,631],{},[261,632],{"alt":633,"src":634},"Husky 自訂檢查流程 : 自訂檢查範例流程","\u002Fimg\u002Fcontent\u002Fhusky-git-hooks-husky.webp",[200,636],{},[203,638,640],{"id":639},"被攔截後該如何修復","被攔截後該如何修復？",[158,642,643,644,647],{},"首先要有一個核心觀念：",[195,645,646],{},"Husky 本身只是一個「在關鍵時間點自動幫你跑指令」的執行工具","。它本身不負責定義規則，也不會自動幫你修復代碼。",[158,649,650,651,373],{},"當提交或推送被 Husky 擋下時，終端機跳出的其實是",[195,652,653],{},"底層檢查工具的報錯訊息",[269,655,656,673],{},[272,657,658,664,665,668,669,672],{},[195,659,660,661,663],{},"如果是 ",[241,662,278],{}," 報錯","：代表程式碼違反了專案設定的 ",[195,666,667],{},"ESLint 語法規範","，或是沒有通過現有的",[195,670,671],{},"單元測試（Test Cases）","。請根據終端機的行數提示，回到原始碼修正語法或修復破掉的業務邏輯測試。",[272,674,675,679,680,683],{},[195,676,660,677,663],{},[241,678,291],{},"：代表專案依賴包含了高風險漏洞，可透過 ",[241,681,682],{},"npm audit fix"," 升級套件，或評估更新依賴版本。",[200,685],{},[203,687,688],{"id":688},"小結",[158,690,691,694,695,452],{},[195,692,693],{},"Husky 本身並不複雜，安裝只需兩行指令","，設定也都透明地記錄在專案檔案中。它的核心價值在於把「本來只能靠人腦記憶手動執行的零散指令」，變成「每次 commit 與 push 時由系統自動強制執行的品質守衛牆」，",[195,696,697],{},"讓語法把關與資安稽核從可有可無的建議，變成不可妥協的標準流程",[699,700,701],"style",{},"html pre.shiki code .sP_rH, html code.shiki .sP_rH{--shiki-default:#59C2FF}html pre.shiki code .skAsU, html code.shiki .skAsU{--shiki-default:#AAD94C}html pre.shiki code .sHCZS, html code.shiki .sHCZS{--shiki-default:#95E6CB}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sOSKZ, html code.shiki .sOSKZ{--shiki-default:#5A6673;--shiki-default-font-style:italic}",{"title":233,"searchDepth":504,"depth":504,"links":703},[704,705,710,711],{"id":205,"depth":504,"text":206},{"id":324,"depth":504,"text":325,"children":706},[707,708,709],{"id":337,"depth":515,"text":338},{"id":395,"depth":515,"text":396},{"id":458,"depth":515,"text":459},{"id":639,"depth":504,"text":640},{"id":688,"depth":504,"text":688},"md",{"src":104,"alt":105},{},{"title":97,"description":100},"pPiR4z7U6lZ7DIj0-JD77ZQs3QNZgag7XaRawJbDvGE",[718,719],{"title":87,"path":88,"stem":89,"description":90,"children":-1},{"title":720,"path":721,"stem":722,"description":723,"children":-1},"三款番茄時鐘線上工具 - 掌控時間的高效工作法","\u002Fblog\u002Ftech\u002Ftomato-web","blog\u002F4.tech\u002F7.tomato-web","透過科學的方法，利用免費線上番茄鐘工具幫助實現平衡專注與休息的最佳方法。",[]]