Featured image of post 套件版本管理與 SemVer 全攻略: package.json 中的版本號是什麼意思?不同的設定對於套件安裝或升級有什麼差異?

套件版本管理與 SemVer 全攻略: package.json 中的版本號是什麼意思?不同的設定對於套件安裝或升級有什麼差異?

帶你深入淺出了解 Semantic Versioning (SemVer) 邏輯,解析 package.json 中的 ^、~ 等符號含義,並分享 pnpm-lock.yaml 如何確保團隊開發環境一致,解決版本衝突問題。

你有沒有遇過這種情況:明明在 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 會自動讀取兩邊的需求,重新計算出一份完美的全新合約。

結語

掌握版本號不是為了考試,而是為了讓你的開發環境「穩如老狗」。下次遇到版本升不上去,別再懷疑人生,你現在已經是領有執照的老司機了!

All rights reserved,未經允許不得隨意轉載
使用 Hugo 建立
主題 StackJimmy 設計