用 Corepack 管理 pnpm 版本
最近幫新人設定環境時才發現目前 pnpm 預設安裝的版本都是 v9,而目前大多專案仍是使用 v8。
考慮到舊的專案可能不適合升級 pnpm 版本,總要有可以降舊版本 pnpm 的方式。
目前在 Mac 上安裝 pnpm 我主要都用 Homebrew 安裝,但這個方式無法指定 pnpm 版本來安裝。
查來查去最理想的大概是使用 Corepack,只好來試試看了…
什麼是 Corepack
Corepack 是一個套件管理工具的管理工具(超繞嘴)。
簡單來說,就是可以管理如 yarn、pnpm 版本的工具。
目前 Corepack 預設內建在 v16.13
以上版本的 Node.js 中,如果使用 Homebrew 安裝 Node.js,則會需要另外安裝 Corepack。
可以透過 npm -g list
檢查目前 Node.js 中是否有 Corepack:
由於 Corepack 目前還算是實驗性工具,所以如果想要使用則需要手動啟用 Corepack:
由於 Corepack 是跟著 Node 版本,因此透過 nvm 或 fnm 切換到第一次使用的 Node 版本,會需要重新啟動 Corepack。
在 Corepack 中使用 pnpm
在 Corepack 啟用後,就可以直接透過 Corepack 使用 pnpm:
接下來只要在 package.json 裡面加上 packageManager
這個屬性,Corepack 就會幫你自動選擇對應的 pnpm 版本:
也就是說,只要在每個專案中寫好 packageManager
,就可以確保其他開發者也使用相同版本的 pnpm 啦!
切換 pnpm 版本
可以透過 corepack use
指令來指定 Corepack 預設的 pnpm 版本:
使用這個指令後,會自動在 package.json 中加上 packageManager
這個屬性,並自動執行安裝:
有 packageManager
這個屬性後,使用其他的套件管理工具的指令會出現錯誤,需要修改 package.json
中的 packageManager
來指定正確的管理工具和版本:
另外,Corepack 是跟著 Node 版本的,所以如果調整了 Node 版本,但又沒有 packageManager
,那就會發現 pnpm 指令失效:
這時候重新啟動 Corepack 使用 pnpm 即可:
指定預設使用的 pnpm 版本
corepack prepare
這個指令可以幫你預先下載指定版本的 pnpm:
如果在指令後面加上 --activate
參數,當專案中沒有 packageManager
這個屬性,但使用了 pnpm 的指令,Corepack 會直接預設幫你使用 corepack prepare --activate
所指定的 pnpm 版本:
若想手動清除 Corepack 的 local 快取,可以使用 corepack cache clean
指令:
再執行 pnpm -v
時,Corepack 會詢問是否要下載 pnpm 版本:
結語
搞懂 Corepack 後,會發現這東西真的很方便,只要指定好 packageManager
就不需要再擔心不同專案間的 pnpm 版本問題。
但撰寫這篇文章時,也剛好看到國外的文章在討論 Node.js 團隊要移除 Corepack 的計劃。
我個人是完全支持的,畢竟使用依賴在 Node.js 中的工具來管理額外安裝的套件版本,總覺得有點彆扭,總覺得 pnpm 這種工具更應該直接獨立出來安裝和管理,而不是依賴在 Node.js 中。
目前 pnpm 也陸續有針對版本管理的討論跟實驗性功能,相信未來應該會有比 Corepack 更好的管理方案。