你有沒有遇過這種情況:明明在 package.json 寫了 ^0.0.3,跑了 pnpm update,最新版都出到 0.1.0 了,結果套件紋風不動?是 pnpm 壞掉了,還是你在玩「原地踏步」?別擔心,你並不孤單,這其實是軟體世界裡的一套「安全保險機制」。
解開 X.Y.Z 的密碼:改裝車的規格
想像你在幫你的愛車換零件,版本號 X.Y.Z(例如 1.2.3)就像是這台車的更新清單:
| 欄位 | 簡述 | 說明 |
|---|---|---|
| X | 大改款 | 這就像是換引擎。換了之後,舊的駕駛習慣可能全都要改,甚至連方向盤的位置都變了,這就是所謂的「破壞性變更」(Breaking Changes)。 |
| Y | 新功能 | 這像是加裝倒車顯影。功能變強了、東西變多了,但你原本的開車方式完全不受影響,是可以無痛升級的。 |
| Z | 小維修 | 這只是補個輪胎皮或換個雨刷。純粹是修補 Bug,如果不看版本號,你可能根本沒發現它更新了。 |
符號的合約精神:保險員的「安全契約」
你在 package.json 寫的那個符號,決定了你的程式碼是會「與時俱進」還是「原地爆炸」。我們把這套規則想像成一份裝修合約:
| 符號 | 範例 (1.2.3) |
升級範圍 | 老司機的白話文 |
|---|---|---|---|
| 無符號 | 1.2.3 |
固定 1.2.3 | 死心塌地:我就要這一個版本,換個螺絲都不行。 |
波浪號 ~ |
~1.2.3 |
< 1.3.0 | 微調維修:只准修 Bug (Z),不准加新功能。 |
脫字符 ^ |
^1.2.3 |
< 2.0.0 | 功能解禁:可以加功能 (Y),但別把引擎 (X) 換掉。 |
特別注意:為什麼 0.x.x 會讓 pnpm 變得保守?
這就是為什麼你的 ^0.0.3 升不上去的原因!在版本號還沒跳到 1.0.0 之前,這在開發界叫做「草創期」。
保險員(pnpm)會變得非常保守:他認為 0.0.x 的每一次更新都可能是大換血! 所以 ^0.0.3 只敢更新到 0.0.4,它連 0.1.0 都不敢跨過去。如果你想升級,就得手動修改 package.json 或使用強制手段。
老司機的超車技巧:強制升級
當自動更新失效,或是你確定要「衝一波」升級到最新版時,可以用這兩招:
| 方法 | 內容 |
|---|---|
| 直接點名法 | 輸入 pnpm add some-package@latest。這就像導演直接下令:「給我換最新的那個演員!」 |
| 互動挑選法 | 輸入 pnpm update --interactive (或 pnpm up -i)。這會列出所有可更新的套件,像選妃一樣讓你勾選。 |
不僅是食譜,更是冷凍調理包:pnpm-lock.yaml
在團隊開發中,pnpm-lock.yaml 就是那份 「絕對不能改動的家傳祕方」:
| 檔案 | 內容 |
|---|---|
package.json (食譜) |
上面寫著「需要麵粉、雞蛋」。但沒說什麼牌子、產地。每個人煮出來的味道(環境)都會歪掉。 |
pnpm-lock.yaml (冷凍調理包) |
它精確記錄了每一種食材的產地、重量。當隊友跑 pnpm install 時,就像打開一模一樣的冷凍調理包,確保「Vibe」完全一致。 |
當遇到「集體追撞」(Lock 檔衝突)時
千萬不要手動修衝突標記!那裡面充滿了機器讀取的雜湊值。最優雅的做法是直接跑:
pnpm install
pnpm 會自動讀取兩邊的需求,重新計算出一份完美的全新合約。
結語
掌握版本號不是為了考試,而是為了讓你的開發環境「穩如老狗」。下次遇到版本升不上去,別再懷疑人生,你現在已經是領有執照的老司機了!