本篇文章由和 Chatgpt 的對話整理而成。
# pnpm
如果系統中已經安裝了 pnpm ,你可以用它來代替 npm 做 local 安裝,而且它有一些很棒的優化。
# 🚀 什麼是 pnpm ?
pnpm 是一個和 npm 、 yarn 類似的 Node.js 套件管理器,但它的特色是:
- 使用 內容可尋址的儲存(Content-Addressable Storage)。
- 套件只會在硬碟中儲存 一份實體副本,不同專案共用。
- 使用 symbolic links 將套件連結到專案的
node_modules,節省大量空間和安裝時間。
# ✅ 使用 pnpm 安裝是 local 嗎?
是的,預設就是 local 安裝,和 npm 一樣。
範例指令:
pnpm install express cors |
這會:
- 安裝
express和cors到當前資料夾(例如my-backend)的node_modules/ - 更新
package.json和pnpm-lock.yaml(pnpm 自己的鎖定檔)
# 📦 pnpm 相較 npm 的優點
| 項目 | npm | pnpm |
|---|---|---|
| 硬碟空間使用 | 每個專案各裝一份 | 套件只裝一份,共用儲存 |
| 安裝速度 | 較慢 | 明顯更快 |
| 安全性與一致性 | OK | 更嚴格、避免隱性依賴(hoisting 限制更嚴格) |
| 鎖定檔格式 | package-lock.json | pnpm-lock.yaml |
# 🧪 轉換專案從 npm → pnpm?
你可以在有 package.json 的資料夾裡,直接執行:
pnpm install |
它會自動生成 pnpm-lock.yaml 並使用 pnpm 的機制處理依賴。
# ⚠️ 注意事項
pnpm的 node_modules 結構不太一樣(非扁平),如果有些工具(或寫死路徑)依賴 npm 的安裝邏輯,可能要調整。- 有些比較舊的套件或工具若不支援
pnpm結構,可能需要額外設定。
# ✅ 總結
你可以放心使用 pnpm 做 local 安裝,它會:
- 作用在目前資料夾
- 節省空間、加快速度
- 幫你建立自己的
pnpm-lock.yaml
只要你系統裡有 pnpm ,就可以隨時用它來取代 npm 安裝流程。而且兩者可以在不同專案中交替使用,不會衝突。
# pnpm 疑問 1
如果 pnpm 共用儲存空間,那是不是代表兩個專案會互相影響?
這個問題問得超關鍵 👏
# ✅ 答案是:「不會互相影響」
雖然 pnpm 確實只在系統中存一份實體套件(類似快取),但它對每個專案的使用方式是 乾淨、獨立的。
# 🔧 原理:pnpm 是用「硬碟快取 + symlink(符號連結)」的方式運作
- 當你在專案 A 裡執行
pnpm install express時:pnpm會把express套件下載到全域的 store 快取資料夾(通常在~/.pnpm-store或C:\Users\你\.pnpm-store)。- 然後在
專案A/node_modules/建立一個 symbolic link,指向那份快取裡的express。
- 如果你之後在專案 B 也安裝了相同版本的
express,它會重複使用快取中的實體檔案,但在專案B/node_modules/建立自己的連結。
🧠 關鍵點在這裡: 每個專案的 node_modules/ 還是自己的結構和相依性圖,只是檔案來源共用而已,不會有邏輯上的干擾。
# 🧪 打個比方
想像兩個人租書:
npm是每人都買一套書放自己房間。pnpm是共用圖書館(快取區),但每人有自己的書架(node_modules),只是借同一本書回來用,不會互相寫筆記或改書內容。
# 🔐 安全性上,pnpm 還更嚴格!
- pnpm 預設會阻止「隱式依賴」的使用(例如 A 安裝了 B,但你卻在 C 裡用 B)。
- 如果某個套件沒有明確列在
package.json,它不會偷偷從其他地方撈來用,這可以防止出錯。
# ✅ 小結:
| 問題 | 答案 |
|---|---|
| 兩個專案會共用實體套件嗎? | ✅ 會,共用快取區域 |
| 兩個專案的依賴會互相干擾嗎? | ❌ 不會,各自 node_modules 獨立 |
| 是否安全? | ✅ 更嚴格、更節省資源 |
# pnpm 疑問 2
一個套件升級或改壞了,會不會波及到其他專案
這點你問得非常精準,因為你已經掌握了共用快取的潛在風險 👍
# 🧯 ✅ ** 正常情況下:** 不會波及其他專案
原因如下:
每個專案的依賴版本是獨立鎖定的
- 你在每個專案的
pnpm-lock.yaml檔案中,已經鎖定了每個依賴及其子依賴的精確版本號。 - 所以只要不刪除 lock 檔,每次
pnpm install都會重建出一模一樣的依賴結構。
- 你在每個專案的
即使快取裡有新版套件,pnpm 不會主動升級其他專案的依賴
- pnpm 只會安裝你在
package.json+pnpm-lock.yaml中明確要求的版本。
- pnpm 只會安裝你在
即使共用快取,pnpm 不會重寫檔案內容
- pnpm 的快取區(store)是唯讀的,快取裡的檔案一旦寫入,就不會被修改。
- 如果有新版本,pnpm 會下載到另一個快取位置,不會覆蓋原本的。
# ⚠️ 有風險的情況 (很少見,但可以發生)
| 情況 | 是否會影響其他專案? | 說明 |
|---|---|---|
| 🛠️ 你手動去改快取資料夾 | ✅ 會 | 千萬別這樣做,因為快取是全域共用的 |
🧹 你清掉全域快取(例如 pnpm store prune 或 rm -rf ~/.pnpm-store ) | ❌ 不會破壞,但重新安裝會用新版本(若沒鎖定) | 有鎖檔就沒問題 |
🧪 你用 --latest 或 --force 全域升級所有套件 | ❌ 不會直接影響其他專案 | 但你要自己確保不會動到其他專案的 lock 檔 |
# 🛡 實務上怎麼防止風險?
- 永遠保留
pnpm-lock.yaml並加入版本控制(Git)。 - 不要直接修改快取目錄(像是
.pnpm-store)。 - 專案之間不要共享同一份
node_modules或 symlink 工程(例如 monorepo 要用 workspace 管理)。 - 使用
pnpm install --frozen-lockfile來確保部署或 CI 階段不會有意外升級。
# ✅ 結論
| 問題:一個套件升級或壞掉,會波及其他專案嗎? |
|---|
| ** 正常使用下:不會。** 因為 pnpm 鎖定了版本,且使用唯讀快取。 |
pnpm 就像是乾淨、獨立又高效的公寓系統:
- 每戶(專案)自己決定要住哪個版本的房子(套件),
- 房東(pnpm)只是節省空間而已,不會擅自裝潢或改建你家。