2051 字
10 分鐘

pnpm 12 穩定嗎?從 RC lockfile 驗證到正式版升級

pnpm 12 已經不是 RC:官方在 2026 年 8 月 26 日發布 v12.0.0。這篇文章原本用 RC 版本整理 lockfile 驗證,現在改以正式版為基準,保留 RC 測試時最值得注意的 dependency cycle、workspace 和 pinned package manager 檢查。

直接結論是:可以把 pnpm 12.0.0 放進隔離的 CI matrix 和 canary,但不要只在本機更新 global pnpm 就宣布全團隊升級。 先固定 Node、registry、pnpm 版本,驗證既有 lockfile 的 frozen install,再在 disposable branch 觀察真正重新解析時的差異;正式環境要保留明確的回退 pin。

先分清正式版、RC 與安裝來源#

pnpm 12.0.0 是正式 release,12.0.0-rc.11 則是升級前的候選版本。至於不帶版本的安裝指令會拿到哪一個 major,仍取決於 registry 的 dist-tag、套件管理器或團隊的版本工具;不要用 npm install --global pnpm 的結果代替專案 pin。

版本或來源適合的用途你要留下的證據
[email protected]正式版升級、canary 與 production CIrelease tag、Node 版本、lockfile diff
[email protected]已結束的 RC 回歸或重現案例RC release note 與測試結果
未指定版本或 latest互動式試用,不適合當部署輸入執行時解析出的實際版本

先查清楚目前執行的是哪一個 pnpm:

Terminal window
pnpm --version
node --version
npm view pnpm dist-tags --json

要測正式版時,請在隔離環境明確安裝和驗證:

Terminal window
npm install --global [email protected]
pnpm --version

團隊若已經使用 Corepack、mise 或其他版本管理器,沿用既有流程即可;重點是把 12.0.0 寫進可審查的 pin,並讓每個 CI job 印出實際版本。

pnpm 12 會影響 lockfile 的四個邊界#

正式版 release note 的重點不只是一個版本號。升級前先把變更拆成可驗證的邊界:

pnpm 12 變更實際要檢查什麼
GitHub、GitLab、Bitbucket 等已知 host 的 Git 依賴統一使用 canonical HTTPS identitylockfile 不再因某台機器能否使用 SSH 而記錄不同 transport;private repository 要在執行機器設定 Git rewrite
pnpm-workspace.yaml 不再默默忽略未知設定拼錯設定時,符合專案 pnpm pin 的執行會回報 ERR_PNPM_UNRECOGNIZED_WORKSPACE_SETTINGS
peer resolution 會以 canonical 順序拆解 dependency cycle相同 dependency graph、不同 importer 或 dependency 順序,應產生 byte-identical lockfile
Linux 的 packageImportMethod: auto 會先嘗試 hardlinkbtrfs 的 warm store 安裝路徑要測時間與 inode 行為;macOS 仍以 clone-first 為主

上述變更不代表所有既有 lockfile 都要重寫。只執行 headless 或 frozen install 時,既有 lockfile 應能被消費;真正觸發 dependency resolution 的時機,才是需要審查 re-key 或 graph 差異的時機。

第一條路徑:只驗證既有 lockfile#

先在乾淨工作副本或 CI runner 測試正式版能否消費目前提交,不要一開始就用 --lockfile-only 產生大量 diff:

Terminal window
git status --short
pnpm --version
pnpm install --frozen-lockfile
git diff --exit-code -- pnpm-lock.yaml

如果 frozen install 失敗,先閱讀 pnpm frozen lockfile 錯誤怎麼修,分辨是 manifest 漂移、pnpm pin 不一致、registry 差異,還是正式版的新行為。不要為了讓 pipeline 繼續就刪除 lockfile。

這條路徑的完成條件是:pnpm 版本、Node 版本、registry 與 lockfile 都能被記錄,安裝不改寫 pnpm-lock.yaml,接著 lint、test 和 build 都通過。它不能證明重新解析一定沒有差異,但能先確認升級不會破壞既有提交。

第二條路徑:在 disposable branch 觀察重新解析#

只有在第一條路徑通過後,才在 disposable branch 或暫存工作副本重新解析:

Terminal window
cp pnpm-lock.yaml /tmp/pnpm-12-before-resolve.yaml
pnpm install --lockfile-only
git diff -- package.json pnpm-workspace.yaml pnpm-lock.yaml

把 diff 分成三類審查:

  1. manifest 或 catalog 刻意改動造成的版本更新。
  2. dependency cycle、peer variant 或 importer 順序造成的 canonical re-key。
  3. 不應出現的 registry、integrity、無關套件版本或 dependency graph 變更。

pnpm 12 的 release note 明確說明,第一次真的重新解析時,cycle-heavy package 的既有 peer variant 可能只重建一次;這不等於每次 pnpm install 都會漂移。若無關套件也被改寫,先保存最小重現案例,再決定是否暫停升級。

Git 依賴:讓 SSH 私有倉庫留在機器設定#

pnpm 12 對 GitHub、GitLab、Bitbucket 的已知 host 會把不同寫法視為同一個 repository identity,lockfile 不再記錄該 host 的 SSH URL。公開 archive 可用時會走 host 的 archive;需要權限的 repository 則透過 canonical HTTPS URL 執行 Git 操作。

如果私有倉庫在 CI 必須透過 SSH 取用,依官方 release note 把 rewrite 設在執行機器,而不是把某台機器的 SSH URL 硬寫進專案 lockfile:

Terminal window
git config --global url."[email protected]:".insteadOf https://github.com/

這個設定應由 CI image 或 runner provisioning 管理,並用最小權限的 deploy key 或既有認證方式驗證。不要把 token、私鑰或帶有帳密的 URL 寫入 package.json、lockfile 或文章範例。

workspace 設定拼錯,pnpm 12 會更早告訴你#

過去 pnpm-workspace.yaml 中不認得的設定可能被靜默忽略;pnpm 12 會回報未知設定,若專案 pin 的 pnpm 版本符合目前執行版本,命令會失敗並給出 ERR_PNPM_UNRECOGNIZED_WORKSPACE_SETTINGS。這是好事,但會讓原本「看似成功」的 CI 變成明確失敗。

升級前先在 workspace 內找出拼字或版本差異,並保留檢查設定的能力:

Terminal window
pnpm config list
pnpm install --frozen-lockfile

pnpm config 子命令不會因為未知 workspace setting 而無法讀取設定,因此可以先用它確認問題,再修正 pnpm-workspace.yaml。修正設定後要把 manifest、workspace 檔案和 lockfile 分開審查,避免把 typo 修復誤判成 resolver 變更。

CI matrix 不要只測一台 macOS#

正式版升級至少要有一個乾淨 runner,並依專案實際部署環境覆蓋 Node、作業系統、檔案系統和 cache 狀態:

  • cold install 與 warm store install 各一次。
  • frozen install、lint、test、build 都通過。
  • monorepo 的 importer 順序、peer dependency、workspace: 和 catalog 案例都存在。
  • Linux btrfs 若使用 packageImportMethod: auto,要觀察 hardlink 路徑;不要把 btrfs 結果套到 ext4 或 macOS。
  • 若含 private Git dependency,CI runner 必須用與 production 相同的認證與 Git rewrite。

同一份 package.jsonpnpm-workspace.yaml 和 lockfile 在兩個乾淨工作副本中重新解析,若結果不同,先比較 Node、pnpm、registry、環境變數和檔案系統,不要先修改 lockfile 來掩蓋差異。

升級與回退的最小流程#

可以把升級拆成這 6 個可審查步驟:

  1. [email protected] 建立獨立 CI job,保留現有 stable major 的 job。
  2. 在 clean runner 執行 frozen install,確認 lockfile 沒有被改寫。
  3. 在 disposable branch 執行 lockfile-only resolution,分類所有 diff。
  4. 修正 workspace unknown settings,補上 private Git dependency 的 runner 設定。
  5. 執行 lint、test、build 與實際 packaging/deploy smoke test。
  6. 通過 canary 後才把專案 pin 與 production image 一起更新,並保留上一個可重現版本。

若需要明確 pin,可以在專案的 package.json 保留 package manager 宣告:

{
"packageManager": "[email protected]"
}

回退時不要只把 global pnpm 降版;要同時還原 package manager pin、CI image、Node、registry 設定和 lockfile。這樣才能知道失敗是 resolver、執行環境還是應用程式測試造成的。

結論:正式版可測,但證據要跟著 pin 走#

pnpm 12.0.0 已正式發布,適合開始做團隊升級和 CI canary。它對 known-host Git dependency、workspace typo、dependency cycle 與 Linux package import 都有可觀察的行為變更;最安全的判斷方式不是看版本號,而是以固定輸入重跑 frozen install、重新解析、測試與 build,並留下能回退的 pin 和 lockfile 證據。

常見問題#

Q: pnpm 12 已正式發布,可以直接執行 npm install --global pnpm 嗎?#

A: 不建議把未指定版本當成部署輸入。registry 的 latest、版本管理器和專案 pin 可能不同;請用 [email protected] 明確安裝或沿用團隊版本工具,並在 CI 印出 pnpm --version

Q: pnpm 12 會讓所有既有 lockfile 重新產生嗎?#

A: 不會。既有 lockfile 可以由 frozen install 消費;只有 dependency graph、manifest 或設定真的觸發重新解析時,才可能看到 cycle 或 peer variant 的 canonical re-key。任何無法解釋的 registry、integrity 或無關套件差異都應先保存案例。

Q: frozen install 在升級後失敗,應該刪除 lockfile 嗎?#

A: 不要先刪除。先確認 package manager pin、Node、registry、manifest 和 workspace 設定,再依錯誤內容判斷是否需要在隔離分支重新解析。刪除 lockfile 會讓真正的相容性問題更難追蹤,也會擴大版本變更範圍。

參考資料:

pnpm 12.0.0 release notes

pnpm Docs:packageManager

pnpm Docs:pnpm install

pnpm Docs:Settings

pnpm 12 穩定嗎?從 RC lockfile 驗證到正式版升級
https://laplusda.com/posts/pnpm-12-rc-5-lockfile-check/
作者
Zero
發佈於
2026-08-14
許可協議
CC BY-NC-SA 4.0
這篇文章有幫助嗎?

回報錯字、失效連結,或告訴我你想看的延伸主題。