Node.js 依赖管理(二)—版本号管理1.x.x

原文链接:Node.js 依赖管理(二)—版本号管理1.x.x

本文拜读百度@小蘑菇哥哥Node.js 中的依赖管理正文从这里开始~

在引入某个依赖项时,采用如下代码:

npm i xxx -D 或 npm i xxx -S

如果没有明确的指定xxx的引用版本,则会默认安装最新版本的包,等同于:

 npm i xxx@latest -D

最后生成的package.json中的依赖项版本如下:

P9-iZiOGY2he8gSr_photo_1549875074.png


以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

下面是其他相关文章推荐:

Node.js 依赖管理(一)—区分dependencies和devDependencies

Node.js 依赖管理(三)—package-lock.json详解

猜你喜欢

转载自blog.csdn.net/NovenQingTang/article/details/87009258
今日推荐