pnpm 12.3.0 出現 SyntaxError 怎麼修?先查 packageManager shim
如果專案的 package.json 指定 [email protected] 或 [email protected],但執行環境的 PATH 先找到較舊 pnpm,可能在每次啟動 package manager shim 時直接看到 SyntaxError: Invalid or unexpected token。這個錯誤看起來像 Node.js 或 cache 壞掉,實際上要先確認版本委派鏈。
直接答案是:先確認真正被執行的 pnpm 路徑和版本,再把專案 pin 到至少 12.3.2;本次查核 registry 的 latest 與 latest-12 是 12.3.4。 不要一開始就刪除 store 或重建 lockfile,因為那不會修正 PATH 上的舊 shim。
先收集四個版本訊號
在修改任何設定前,先從同一個 shell 執行:
command -v pnpmpnpm --versionnode --versionnode -p "require('./package.json').packageManager ?? '(none)'"再檢查 package.json 是否同時有 packageManager 和 devEngines.packageManager:
node -e "const p=require('./package.json'); console.log(JSON.stringify({packageManager:p.packageManager, devEngines:p.devEngines?.packageManager}, null, 2))"要記錄的不是只有一個版本號,而是:
command -v pnpm指向哪個安裝位置,以及是否有多個 shell/CI 路徑。- 目前 pnpm 與 Node.js 版本。
packageManager是否精確 pin 到 12.3.0 或 12.3.1。- 失敗是在 Corepack、wrapper,還是 pnpm 自己的 native shim 發生。
這個錯誤和 Corepack 不一定有關
pnpm issue #14502 的回報情境是:專案 pin 到 pnpm 12.3.0/12.3.1,PATH 上先找到較舊的 pnpm,之後 pnpm 執行任何命令都在 shim 階段報 SyntaxError;回報者也明確指出重現環境沒有使用 Corepack。這是 issue 的特定重現,不代表每台機器都會有同樣的啟動鏈。
可以用錯誤堆疊和上面的路徑檢查來分流:
| 看到的線索 | 優先檢查 |
|---|---|
| 堆疊包含 Corepack | Corepack 的 enable、cache 和所解析的 package manager 版本 |
command -v pnpm 指到舊版本,且專案有 packageManager | PATH 順序、shim 與專案 pin |
| 直接執行明確的新版本仍失敗 | Node.js、平台架構、wrapper 安裝方式與新的最小重現 |
不要因為錯誤出現 node: 或 .cjs 就直接把它歸類成 Node.js 版本不相容。先把實際入口、版本和 package manager 欄位對上,才能判斷是哪一層產生語法錯誤。
修補版與目前 stable 怎麼選
pnpm 的 v12.3.2 release note 提到,placeholder 改成無 shebang,讓 pnpm 11 能透過 version store 安裝 pnpm 12;使用 wrapper 安裝時,還要確認 lifecycle scripts 沒有被禁止。這是針對版本安裝/啟動鏈的修正,不宜解讀成所有 SyntaxError 都已經消失。
本次查核 pnpm registry 的結果是:
| 項目 | 版本 | 建議 |
|---|---|---|
latest/latest-12 | 12.3.4 | 新專案或要修補 12.3.x 問題時,先在測試環境驗證 |
| v12.3.2 | 12.3.2 | 目前已知 shim 修補的最低參考版本 |
next-12 | 12.4.0 | 不要因為數字較大就直接放進 production |
若團隊沒有必須留在 12.3.0/12.3.1 的相容性理由,可以先在同一個開發環境安裝目前 stable,再確認專案 pin:
hash -rcommand -v pnpmpnpm --version如果 package.json 還是把版本固定在問題版本,也要將它更新成團隊決定的修補版本,例如:
{}更新後再執行:
pnpm install --frozen-lockfilepnpm --version版本號是示例,不是永久答案;pnpm dist-tags 會改變,正式升級前仍應重新查 registry、在 CI 驗證,並把 lockfile 和 package manager pin 一起審查。
pnpm 的版本欄位要選一個真實來源
pnpm 文件目前同時說明兩種欄位:
packageManager是既有的精確版本宣告,pnpm 12 也可能依它管理 package manager 版本。devEngines.packageManager從 pnpm 11 起支援版本 range,解析後的版本會記錄在 lockfile 的 package manager dependencies。
兩者同時存在時,團隊要明確決定誰是規範來源,並在 CI 印出解析結果。若目標是可重現建置,通常先採 exact pin,再用 lockfile、CI image 和 Node.js 版本一起固定;若要用 range,也要明確寫出允許的修補範圍和升級檢查週期。
如果 12.3.4 仍然失敗
升到修補版後仍失敗,不要繼續盲目清 cache。保留下面資料建立新的最小重現:
- 作業系統、CPU 架構和 Node.js 版本。
command -v pnpm、pnpm --version與package.json的 package manager 欄位。- 完整但已遮蔽路徑與秘密的錯誤堆疊。
- 是否透過 npm、Corepack、pnpm version store、Bun、Deno 或 CI wrapper 安裝。
[email protected]的明確版本執行結果,以及pnpm install --frozen-lockfile的結果。
這樣可以把「已知的 12.3.0/12.3.1 shim 回歸」和新的平台、wrapper 或 Node.js 問題分開,不會用錯誤的 workaround 掩蓋真正原因。
常見問題
只更新全域 pnpm 就夠了嗎?
不一定。如果專案的 packageManager 仍然 pin 到問題版本,啟動流程可能繼續解析到舊版本。全域版本、PATH、package.json 欄位和 lockfile 要一起檢查。
可以直接退回 pnpm 12.2.1 嗎?
12.2.1 是 issue 回報中的對照版本,不應直接視為目前最佳解。若要暫時回復,先確認 lockfile、Node.js 和 CI 都能重現,再排入至少 12.3.2 以上的修補版本升級。
刪除 pnpm store 能修好這個 SyntaxError 嗎?
通常不是第一步。這個案例發生在 shim/版本委派階段,應先查路徑和 pin;只有確認是下載內容損壞或 store 狀態異常,才依 pnpm 官方建議處理 cache 或 store。
參考資料:
pnpm issue #14502:pnpm 12.3.0/12.3.1 shim 啟動錯誤
pnpm v12.3.2 release:修正 placeholder shebang
回報錯字、失效連結,或告訴我你想看的延伸主題。