ERR_PNPM_IGNORED_BUILDS 解法:pnpm approve-builds 完整教學
本篇重點
pnpm install 突然炸出這段,然後整個安裝被中止?
[ERR_PNPM_IGNORED_BUILDS] Ignored build scripts: sharp@0.34.5, unrs-resolver@1.12.2
Run "pnpm approve-builds" to pick which dependencies should be allowed to run scripts.
Aborting installation.
pnpm install has failed.
這不是你的專案壞了,是 pnpm 的安全政策在攔你。這篇給你最短路徑的解法、解釋為什麼 --force 和 pnpm rebuild 都救不了,以及 approve-builds 本身藏的兩個地雷(很多人誤按 Enter 之後卡在「沒東西好選」)。
最短解法(30 秒版)
pnpm approve-builds # 上下鍵移動、「空白鍵」打勾、Enter 確認
兩個關鍵,都是地雷:
- 一定要用「空白鍵」勾選 sharp 和 unrs-resolver,不要直接按 Enter
- 最後的
(y/N)確認要打y,預設是 N
跑完再 pnpm install 就會過了。這個 approval 是 user-level 的,一台機器跑一次就夠,之後 fresh clone 同一個 repo 不會再問。
為什麼會發生?
任何 npm package 都可以掛 postinstall script(編譯 native binary、下載資源),這也是供應鏈攻擊的常見入口。所以 pnpm 新版預設不跑任何 dependency 的 build script,要你明確允許。
以 Next.js 專案為例,有兩個依賴必須跑 native build:
| Package | 為什麼要 build |
|---|---|
sharp | 圖片最佳化核心,要編 libvips(C++)。沒編好會 fallback 到純 JS 版,效能差 5~10 倍 |
unrs-resolver | Next.js 16 的新 module resolver(Rust),要編出 .node binary |
為什麼 --force、rebuild、onlyBuiltDependencies 都沒用?
這是最容易鬼打牆的地方。pnpm 11 把 build approval 拉到比 lockfile 更高的層級:
package.json的pnpm.onlyBuiltDependencies是「這個 repo 同意跑哪些 build」pnpm approve-builds是「你這個人同意這台機器跑那些 build」
兩件事,缺一不可。 所以就算 package.json 白名單列好了,沒過 approve-builds 這關,pnpm install --force、pnpm rebuild sharp 全部照樣顯示 Ignored build scripts。
repo 端的白名單還是要寫(讓 CI 和隊友的 fresh clone 直接吃到):
{
"pnpm": {
"onlyBuiltDependencies": ["sharp", "unrs-resolver"]
}
}
⚠️ 不要圖快用
pnpm config set ignore-scripts false,那是 global 放行所有 package,把供應鏈防線整個拆掉。
誤按 Enter 之後:「There are no packages awaiting approval」
approve-builds 的 prompt 寫著 Press <space> to select,但很多人下意識直接按 Enter,pnpm 會把它解讀成「看過名單、全部不准跑」,並寫進 user-level state。之後再跑 pnpm approve-builds 只會回你:
There are no packages awaiting approval
因為決議已下,pnpm 不再問。兩種救法:
# 方案 A:直接指名重新互動(pnpm 11.1+)
pnpm approve-builds --interactive sharp unrs-resolver
# 方案 B:手動編輯 pnpm 的 user state,把 false 紀錄砍掉再重跑
# macOS 路徑在 ~/Library/pnpm/ 之下的 yaml 檔
只想跑 dev mode?可以先放生
如果你現階段只需要 pnpm dev 改東西,可以完全跳過 approve-builds:sharp 沒編譯只影響 production 的圖片最佳化,dev mode 跑得起來。等要跑 production build 再回來處理。
這個坑是我在用 OpenSpec 重構老專案、幫前端跑 pnpm create next-app 時踩到的,完整的踩坑過程(包含 --frozen-lockfile exit 0 但 build 沒跑的陷阱)記錄在 OpenSpec 重構老專案 Ep-3。
相關文章
OpenSpec 重構老專案 Ep-3:Next.js 16 前端開工
前端用 pnpm create next-app 開工。這篇拆解那行指令背後的 8 個 flag,完整解掉 ERR_PNPM_IGNORED_BUILDS(Ignored build scripts: sharp)的 approve-builds 陷阱、Node 版本怎麼對齊、首頁怎麼砍到 14 行驗證後端。
重構筆記OpenSpec 重構老專案 Ep-4:用 propose 設計 Sanctum 認證
認證功能開工。這篇用 /opsx:propose 走一次設計,帶你看 4 個 artifact 各在做什麼、Sanctum SPA 為什麼贏過 token 模式,還把最容易踩坑的「四觸點對齊」釘進 spec 級 requirement。純設計 walkthrough,看完就懂為什麼先寫 spec。
重構筆記OpenSpec 重構老專案 Ep-5:交易核心與競態防線
碳匯交易核心一天從 propose 跑到 archive。挑 4 個設計決策講透:角色用 row 存在性推導、state machine 雙保險、同時購買競態用 DB transaction + lockForUpdate + UNIQUE 三層防線擋住。想學 Laravel 併發防護就看這篇。