npm 中如何下載特定的組件版本
- 2019 年 12 月 4 日
- 筆記
本文作者:IMWeb helinjiang 原文出處:IMWeb社區 未經同意,禁止轉載
本文詳細討論了 npm 中依賴版本的版本號配置寫法及比較。
1. 開篇
為了更好的進行說明,我們選擇了 lodash 來演示,因為它是被其他模組依賴最多的模組之一。本文是在 windows 7 64位系統中進行測試,npm 版本為 v3.8.1,其他的平台和 npm 版本在某些提示上可能會稍有不同。
運行 npm install lodash --save 命令,安裝下載 loadash,此時 package.json 文件中會是這個樣子的:
{ "name": "test", "dependencies": { "lodash": "^4.11.1" } }有沒注意到那個 ^4.11.1? 4.11.1 是版本號很容易理解(這裡只是當前的最新版本,後續 loadash 版本更新之後可能會有變化),前面的 ^ 符號是什麼鬼?你甚至還見過這樣的 ~4.11.1 、 4.11.1 、<4.11.1 等寫法,都有什麼區別?
2. 語義化的版本控制
在進入主題之前,我們得先了解一個很重要的概念,就是語義化的版本控制(Semantic Versioning Specification (SemVer)),目前的版本為 v2.0.0。具體規則請看官網文檔,這裡只是簡單介紹。
語義化版本格式為:主版本號.次版本號.修訂號,例如 4.11.1,版本號遞增規則如下:
- 主版本號:當你做了不兼容的 API 修改,
- 次版本號:當你做了向下兼容的功能性新增,
- 修訂號:當你做了向下兼容的問題修正。
我們先假設所有的 npm 包的版本命名都符合這個規範,這是討論的基礎。
3. 版本號的配置寫法
在 package.json 文件中,我們配置 dependencies 等依賴關係時,有幾種配置方式。
3.1 ^ (caret,插入符)和 ~ (tilde,波浪符)
^ (caret,插入符)和 ~ (tilde,波浪符)是我們見得最多的,也是最容易迷惑的,我們放在一起來對比,就會更明白些。除了在 package.json 中直接指定之外,我們也可以運行 npm install lodash@^3.3.0 或 npm install lodash@~3.3.0 來直接安裝。
3.1.1 含義和對比
用法舉例 | 含義 | 範圍 | 備註 |
|---|---|---|---|
^4.11.1 | Compatible with 4.11.1 | 4.11.1 <= version < 5.0.0(4.x.x 且 >=4.11.1) | 主版本號不變 |
~4.11.1 | Reasonably close to 4.11.1 | 4.11.1 <= version < 4.12.0(4.11.x 且 >=4.11.1) | 主版本號和次版本號都不變 |
很難用準確的詞去翻譯它們的含義,自己去查字典吧。
從其定義來看,使用 ^ 會更激進,因為它會獲得「儘可能新的且能夠保持兼容性的版本」;而使用 ~ 會更溫和更保險,因為它會獲得「儘可能靠近指定版本的升級版本」。
當它們也有共同點:
- 當通過這兩種方式獲取的結果中,主版本號一定是不變的,因為主版本號意味這 API 不兼容。
- 可選版本的最低版本號都是大於或等於指定的版本,不能比它還低;如果在該範圍內沒有任何版本,則會報錯如下。
3.1.2 例外場景 0.x.x
任何規則都有例外。0.x.x 版本意味著「Anything can change at any time.」。主版本號為 0是為了做快速開發。在版本成型之前,開發者可以任意更改其程式碼,甚至做不兼容的變更而不受約束,然後通過修改次要版本,來控制版本;如果你的軟體被用於正式環境,或已經有了穩定的 API 被使用者依賴,則將其升級到 1.0.0 版本或以上。
因此,針對 0.x.x,指定其依賴版本號時會更趨于謹慎,而 ^ 的行為也變得和 ~ 一樣了。例如 ^0.3.0 和 ~0.3.0 取值都是 0.3.0 <= version < 0.4.0
3.1.3 自測一下
我們以 lodash 為例,這裡有幾份測試用例,如果你都能算對,那麼說明你明白了其中的區別了。為了便於討論,我們先列出 lodash 的所有有效版本,運行命令 npm view lodash versions,獲得結果如下:
[ '0.1.0', '0.2.0', '0.2.1', '0.2.2', '0.3.0', '0.3.1', '0.3.2', '0.4.0', '0.4.1', '0.4.2', '0.5.0-rc.1', '0.5.0', '0.5.1', '0.5.2', '0.6.0', '0.6.1', '0.7.0', '0.8.0', '0.8.1', '0.8.2', '0.9.0', '0.9.1', '0.9.2', '0.10.0', '1.0.0-rc.1', '1.0.0-rc.2', '1.0.0-rc.3', '1.0.0', '1.0.1', '1.0.2', '1.1.0', '1.1.1', '1.2.0', '1.2.1', '1.3.0', '1.3.1', '2.0.0', '2.1.0', '2.2.0', '2.2.1', '2.3.0', '2.4.0', '2.4.1', '2.4.2', '3.0.0', '3.0.1', '3.1.0', '3.2.0', '3.3.0', '3.3.1', '3.4.0', '3.5.0', '3.6.0', '3.7.0', '3.8.0', '3.9.0', '3.9.1', '3.9.2', '3.9.3', '3.10.0', '3.10.1', '4.0.0', '4.0.1', '4.1.0', '4.2.0', '4.2.1', '4.3.0', '4.4.0', '4.5.0', '4.5.1', '4.6.0', '4.6.1', '4.7.0', '4.8.0', '4.8.1', '4.8.2', '4.9.0', '4.10.0', '4.11.0', '4.11.1' ]
測試用例 | 返回結果 |
|---|---|
^4.11.2 | error |
~4.11.2 | error |
^4.8.1 | 4.11.1 |
~4.8.1 | 4.8.2 |
^3.9.1 | 3.10.1 |
~3.9.1 | 3.9.3 |
^3.8.3 | 3.10.1 |
~3.8.3 | error |
^0.3.0 | 0.3.2 |
~0.3.0 | 0.3.2 |
3.1.4 "npm install xx --save" 不再使用 ~
npm 版本 在 v1.4.3 做了一次更新 (Node v0.10.26(Stable)開始將 npm 升級到 v1.4.3), npm install xx --save 之後,保存在 package.json 文件中的依賴版本號前面,將使用 ^ (caret,插入符),而不是 ~ (tilde,波浪符)。
Default
npm install --saveand its counterparts to use the^version specifier, instead of~. (0a3151c,@mikolalysenko)
3.2 大於或小於指定版本
使用大於號(>)或小於號(<)的場景會比較少見,但 npm 也是支援的,
用法舉例 | 含義 | 範圍 |
|---|---|---|
>4.11.1 | 大於 4.11.1 的最新版本 | version > 4.11.1 |
<4.11.1 | 小於 4.11.1 的最新版本 | version < 4.11.1 |
測試用例 | 返回結果 |
|---|---|
>3.8.1 | 4.11.1 |
<3.8.1 | 3.8.0 |
3.3 等於指定版本
可以使用等號(=),也可以不寫。即 "lodash":"=3.8.0" 和 "lodash":"3.8.0" 是一樣的意思。我們也可以通過 npm install [email protected] 來安裝指定版本。