1. 程式人生 > >Node.js 依賴管理(二)—版本號管理1.x.x

Node.js 依賴管理(二)—版本號管理1.x.x

不同的 .json span 同時 文章 enc tps The 官方

原文鏈接:https://www.novenblog.xin/detail/?id=67

本文拜讀百度@小蘑菇哥哥Node.js 中的依賴管理正文從這裏開始~

在引入某個依賴項時,采用如下代碼:

npm i xxx -D 或 npm i xxx -S

如果沒有明確的指定xxx的引用版本,則會默認安裝最新版本的包,等同於:

 npm i xxx@latest -D

最後生成的package.json中的依賴項版本如下:

技術分享圖片

以a.b.c舉例,詳解版本號

a.b.c版本號的含義如下:

a - 主要版本(也叫大版本,major version)

大版本的升級很可能意味著與低版本不兼容的 API 或者用法,是一次顛覆性的升級(想想 webpack 3 -> 4)。

b - 次要版本(也叫小版本,minor version)

小版本的升級應當兼容同一個大版本內的 API 和用法,因此應該對開發者透明。所以我們通常只說大版本號,很少會精確到小版本號。

特殊情況是如果大版本號是 0 的話,意味著整個包處於內測狀態,所以每個小版本之間也可能會不兼容。所以在選擇依賴時,盡量避開大版本號是 0 的包。

c - 補丁 (patch)

一般用於修復 bug 或者很細微的變更,也需要保持向前兼容。

之後我們看一下常規的版本號寫法:

“1.2.3” - 無視更新的精確版本號

表示只依賴這個版本,任何其他版本號都不匹配。在一些比較重要的線上項目中,我比較建議使用這種方式鎖定版本。前陣子的 npm 挖礦以及 ant-design 彩蛋,其實都可以通過鎖定版本來規避問題(彩蛋略難一些,挖礦是肯定可以規避)。

“^1.2.3” - 兼具更新和安全的折中考慮

這是 npm i xxx —save 之後系統生成的默認版本號(^ 加上當前最新版本號),官方的定義是“能夠兼容除了最左側的非 0 版本號之外的其他變化”(Allows changes that do not modify the left-most non-zero digit in the [major, minor, patch] tuple)。這句話很拗口,舉幾個例子大家就明白了:

  • “^1.2.3” 等價於 “>= 1.2.3 < 2.0.0”。即只要最左側的 “1” 不變,其他都可以改變。所以 “1.2.4”, “1.3.0” 都可以兼容。

  • “^0.2.3” 等價於 “>= 0.2.3 < 0.3.0”。因為最左側的是 “0”,所以這個不算,順延到第二位 “2”。那麽只要這個 “2” 不變,其他的都兼容,比如 “0.2.4” 和 “0.2.99”。

  • “^0.0.3” 等價於 “>= 0.0.3 < 0.0.4”。這裏最左側的非 0 只有 “3”,且沒有其他版本號了,所以這個也等價於精確的 “0.0.3”。

從這幾個例子可以看出,^ 是一個更新和安全兼容的寫法。一般大版本號升級到 1 就表示項目正式發布了,而 0 開頭就表示還在測試版,這也是 ^ 區別對待兩者的原因。

“~1.2.3” - 比 ^ 更加安全的小版本更新

關於 ~ 的定義分為兩部分:如果列出了小版本號(第二位),則只兼容 patch(第三位)的修改;如果沒有列出小版本號,則兼容第二和第三位的修改。我們分兩種情況理解一下這個定義:

“~1.2.3” 列出了小版本號(2),因此只兼容第三位的修改,等價於 “>= 1.2.3 < 1.3.0”。

“~1.2” 也列出了小版本號,因此和上面一樣兼容第三位的修改,等價於 “>= 1.2.0 < 1.3.0”。

“~1” 沒有列出小版本號,可以兼容第二第三位的修改,因此等價於 “>= 1.0.0 < 2.0.0”

和 ^ 不同的是,~ 並不對 0 或者 1 區別對待,所以 “~0” 等價於 “>= 0.0.0 < 1.0.0”,和 “~1” 是相同的算法。比較而言,~ 更加謹慎。當首位是 0 並且列出了第二位的時候,兩者是等價的,例如 ~0.2.3 和 ^0.2.3。

在 nodejs 的上古版本(v0.10.26,2014年2月發布的),npm i —save 默認使用的是 ~,現在已經改成 ^ 了。這個改動也是為了讓使用者能最大限度的更新依賴包。

“1.x” 或者 “1.“ - 使用通配符
這個比起上面那兩個符號就好理解的多。x(大小寫皆可)和
的含義相同,都表示可以匹配任何內容。具體來說:

“*” 或者 “” (空字符串) 表示可以匹配任何版本。

“1.x”, “1.*” 和 “1” 都表示要求大版本是 1,因此等價於 “>=1.0.0 < 2.0.0”。

“1.2.x”, “1.2.*” 和 “1.2” 都表示鎖定前兩位,因此等價於 “>= 1.2.0 < 1.3.0”。

因為位於結尾的通配符一般可以省略,而常規也不太可能像正則那樣把匹配符寫在中間,所以大多數情況通配符都可以省略。使用最多的還是匹配所有版本的 * 這個了。

“1.2.3-beta.2” - 帶預發布關鍵詞的,如 alpha, beta, rc, pr 等
先說預發布的定義,我們需要以包開發者的角度來考慮這個問題。假設當前線上版本是 “1.2.3”,如果我作了一些改動需要發布版本 “1.2.4”,但我不想直接上線(因為使用 “~1.2.3” 或者 `^1.2.3” 的用戶都會直接靜默更新),這就需要使用預發布功能。因此我可能會發布 “1.2.4-alpha.1” 或者 “1.2.4-beta.1” 等等。

理解了它誕生的初衷,之後的使用就很自然了。

“>1.2.4-alpha.1”,表示我接受 “1.2.4” 版本所有大於1的 alpha 預發布版本。因此如 “1.2.4-alpha.7” 是符合要求的,但 “1.2.4-beta.1” 和 “1.2.5-alpha.2” 都不符合。此外如果是正式版本(不帶預發布關鍵詞),只要版本號符合要求即可,不檢查預發布版本號,例如 “1.2.5”, “1.3.0” 都是認可的。

“~1.2.4-alpha.1” 表示 “>=1.2.4-alpha.1 < 1.3.0”。這樣 “1.2.5”, “1.2.4-alpha.2” 都符合條件,而 “1.2.5-alpha.1”, “1.3.0” 不符合。

“^1.2.4-alpha.1” 表示 “>=1.2.4-alpha.1 < 2.0.0”。這樣 “1.2.5”, “1.2.4-alpha.2”, “1.3.0” 都符合條件,而 “1.2.5-alpha.1”, “2.0.0” 不符合。

版本號還有更多的寫法,例如範圍(a - b),大於小於號(>=a <b),或(表達式1 || 表達式2)等等,因為用的不多,這裏不再展開。詳細的文檔可以參見 semver,它同時也是一個 npm 包,可以用來比較兩個版本號的大小,以及是否符合要求等。

下面是其他相關文章推薦:

  • Node.js 依賴管理(一)—區分dependencies和devDependencies

  • Node.js 依賴管理(三)—package-lock.json詳解

Node.js 依賴管理(二)—版本號管理1.x.x