本篇重點
- npm install 有無指定版本的差異
- npm install 已安裝套件再次安裝的情境
- npm 設定檔的分工設計
- npm 相依套件的分類
- 語意化版本(SemVer)、符號(^、~)的實際安裝範圍
- npm update 是一個依版本規則自動前進的更新工具
- npm update 有無指定套件的差異
- npm 降版本需求使用 npm install,不能使用 npm update
npm install 行為機制
有無指定版本的差異
當執行 npm i <package> 指令時,npm 會根據指令後方是否帶有版本號,決定下載策略及對設定檔的變更方式。
- 未指定版本:預設下載該套件在 npm registry 標記為
latest的版本(通常是最新穩定版)。安裝後,package.json預設會在版本號前加上^符號(例如"lodash": "^4.17.21"),表示未來允許更新至該大版本下的最新小版本。 - 指定版本:使用
npm i <package>@<version>指定精確版本(如1.2.3),package.json會移除版本符號,直接記錄該固定數值。若指定版本範圍(如@1.x),則安裝該範圍內的最新版。
1 | # 未指定套件版本 |
已安裝套件再次安裝的情境
- 版本一致:
node_modules中的套件已完整符合package-lock.json描述的狀態(包含版本、來源與完整性),npm 會續用現有套件不重新下載。 - 版本不一致(升降級):宣告版本和現有
node_modules、package-lock.json不同,npm 會移除舊版並安裝新版,同時更新package-lock.json。
檔案間的連動關係
npm 專案中,透過以下三部分來維持狀態同步:
- package.json:定義專案「允許使用」的套件版本範圍。
- package-lock.json:鎖定專案「實際安裝」的確切版本與依賴樹。
- node_modules:存放套件原始碼的實體資料夾。
安裝過程中,npm 會根據 package-lock.json 的狀態決定執行行為。
Lock 檔不存在時: npm 依據 package.json 的版本範圍(如 ^1.0.0)向 Registry 查詢符合條件的最新版本(例如 1.5.0)。安裝後,此確切版本會被記錄在 package-lock.json,但 package.json 的宣告範圍維持不變。
Lock 檔存在時:
- 範圍一致:若
package.json的描述與 Lock 檔記錄一致,npm 優先依照 Lock 檔進行安裝,確保環境穩定。 - 範圍衝突:若
package.json導致範圍與 Lock 檔不符,npm 會以package.json為準下載新版,再回頭更新package-lock.json以維持同步。
取得實際套件版本的方法
查看 package-lock.json
直接在
package-lock.json中搜尋套件名稱,查看 version 欄位。package-lock.json 1
2
3"node_modules/some-lib": {
"version": "1.5.0",
}使用 npm 指令查詢
查詢指定套件版本,輸出會顯示目前專案中實際安裝的版本。
npm 1
2
3
4
5# 顯示巢狀依賴,輸出有時較雜
npm list some-lib
# 僅顯示專案直接依賴的版本
npm list some-lib --depth=0透過 node_modules 直接確認
查看
node_modules/some-lib/package.json檔案。package.json 1
2
3
4{
"name": "some-lib",
"version": "1.5.0"
}
相依套件分類
dependencies vs devDependencies
在實務中,區分套件存放位置對於建置(Build)後的產品體積非常重要。
| 類型 | 適用套件範例 | 說明 |
|---|---|---|
| dependencies | react, lodash, axios | 執行環境(Production)必須具備的套件。 |
| devDependencies | typescript, jest, eslint | 僅在開發、測試、建置階段需要的工具。 |
範例
1 | { |
語意化版本
SemVer
遵循 MAJOR.MINOR.PATCH 格式,分別代表主版本號、次版本號與修補版本號。
- MAJOR:不相容的重大變更
- MINOR:向下相容的新功能
- PATCH:向下相容的錯誤修正
版本符號
- ^:允許更新不變更主版本的最新版(不更動最左側非零數字)
- ~:允許更新修補版本(僅允許更新最右側非零數字)
| 符號名稱 | 範例 | 實際安裝範圍 |
|---|---|---|
| Caret (^) 插入符號 | ^1.2.3 | >=1.2.3 且 <2.0.0 |
| Tilde (~) 波浪符號 | ~1.2.3 | >=1.2.3 且 <1.3.0 |
| Exact 精確版本 | 1.2.3 | 僅安裝 1.2.3 |
| Wildcard (*) 萬用字元 | * | 接受任何版本,不建議使用 |
npm update 行為機制
依循規範自動化升級
- 適用於將套件升級至符合
package.json範圍內的最新版本,並同步更新node_modules與package-lock.json。 - 無法指定版本號進行更新,版本規則全權由
package.json決定。
有無指定套件的差異
當未指定套件名稱時:
1 | npm update |
更新所有依賴套件,只要該套件有新版本且符合版本範圍。
適合情境:
- 例行套件維護
- 小版本或 patch 更新
- 專案整體升級
當指定套件名稱時:
1 | npm update some-lib |
更新指定套件和其子套件,指定套件以外的直接依賴不會變動。
適合情境:
- 只想升級特定套件
- 希望控制變動影響範圍
範例
1 | "dependencies":{ |
此設定代表允許更新至 1.x.x 的最新版本。
1 | npm update some-lib |
npm 會自動解析可用版本,並更新:
1 | some-lib@1.9.3 |
結論
npm 的核心邏輯在於提供一套可重現的依賴套件解析機制,把「版本範圍」與「確切版本」明確分離,透過 package.json 控制版本範圍、 package-lock.json 穩定專案確切版本,理解 npm 安裝和更新的實際行為,有助於解讀版本變動、維護專案、多人開發協作,降低不可預期的風險。



