【译】你还认为package.json中^是锁定主版本号,~是修改修订版本号吗?

部分翻译自https://github.com/npm/node-semver
背景
在做项目时,使用的 A 包依赖 B 包版本号 0.0.*,在 C 项目中使用^指定 B 包的依赖版本号,同时引入 A 包,但一直不能被 npm 正确扁平化,特此搞清楚 npm 中包范围的真正含义

结论

^ 一般来说代表的是不包含最左边非零版本号的修改

~ 则要看次版本号是否被指定,次版本号被指定则只包含修订版号的修改

语义化版本号(semver version)

NPM 的版本号采用的 3 元组控制

  1. 主版本号(major):当你做了不兼容的 API 修改,
  2. 次版本号(minor):当你做了向下兼容的功能性新增,
  3. 修订号(patch):当你做了向下兼容的问题修正。
    先行版本号(prerelease)及版本编译元数据可以加到“主版本号.次版本号.修订号”的后面,作为延伸。

范围(Ranges)

一个 比较器 由一个运算符和版本号组成。

  • ​<​ 小于
  • <=​ 小于或等于
  • ​ 大于

  • =​ 大于或等于

  • =​ 等于,如果没有操作符被指定,则认为是等于

版本号的范围由一组比较器决定

Hyphen Ranges ​X.Y.Z - A.B.C​

明确的包含的的组合
​- 1.2.3 - 2.3.4​ := ​>=1.2.3 <=2.3.4​
如果范围的首位是版本号的部分,缺失的部分会用 0 补位

  • ​1.2 - 2.3.4​ := ​>=1.2.0 <=2.3.4​
    如果范围的末位的版本号的部分,则所提供的版本号被接受,且最终范围不会超出所提供的版本号
  • 1.2.3 - 2.3​ := ​>=1.2.3 <2.4.0​
  • 1.2.3 - 2​ := ​>=1.2.3 <3.0.0​

X-Ranges ​1.2.x​ ​1.X​ ​1.2.​ ​

x,X,中的任意一个都可以代表版本号中的一个数值
​ := ​>=0.0.0​ (任意满足的版本)
​1.x​ := ​>=1.0.0 <2.0.0​ (匹配主版本号)
​1.2.x​ := ​>=1.2.0 <1.3.0​ (匹配主版本号和次版本号)

Tilde Ranges ​1.2.3​ ​1.2​ ​~1​

如果指定了次版本号,则允许修订号修改。
如果未指定,则允许次版本号修改。

  • ​~1.2.3​ := ​>=1.2.3 <1.(2+1).0​ := ​>=1.2.3 <1.3.0​
  • ​~1.2​ := ​>=1.2.0 <1.(2+1).0​ := ​>=1.2.0 <1.3.0​ (和 ​1.2.x​ 一样)
  • ~1​ := ​>=1.0.0 <(1+1).0.0​ := ​>=1.0.0 <2.0.0​ (和 ​1.x​ 一样)
  • ~0.2.3​ := ​>=0.2.3 <0.(2+1).0​ := ​>=0.2.3 <0.3.0​
  • ~0.2​ := ​>=0.2.0 <0.(2+1).0​ := ​>=0.2.0 <0.3.0​ (和 ​0.2.x​ 一样)
  • ​~0​ := ​>=0.0.0 <(0+1).0.0​ := ​>=0.0.0 <1.0.0​ (和 ​0.x​ 一样)
  • ​~1.2.3-beta.2​ := ​>=1.2.3-beta.2 <1.3.0​ 注意版本号大于或者等于 beta.2 的 1.2.3 的先行版本会被允许。1.2.3-beta.4 会被包含,但是 1.2.4-beta.2 会因为元组版号不一致而不被包含。(注意会先比较先行版本号)

Caret Ranges ​^1.2.3​ ​^0.2.5​ ​^0.0.4​

允许不包括元组版本号中最左边的非零版号的修改。换而言之,​^1.0.0​ 允许修改次版本号以及修订版号。​^0.0.x​ 则不被允许修改。
相当一部分作者将”0.x’’版本视作”x’’是的“breaking-change”指标。
当作者会在 ​0.2.4​ ~ ​0.3.0​ 作出‘“breaking-change” 时,使用 Caret ranges 是一个合适的选择。 但是一般情况下 ​0.2.4​ 和 ​0.2.5​ 之间不会有“breaking-change”,只会有一些增量性的更新.

  • ^1.2.3​ := ​>=1.2.3 <2.0.0​
  • ​^0.2.3​ := ​>=0.2.3 <0.3.0​
  • ^0.0.3​ := ​>=0.0.3 <0.0.4​
  • ^1.2.3-beta.2​ := ​>=1.2.3-beta.2 <2.0.0​ 注意版本号大于或者等于 beta.2 的 1.2.3 的先行版本会被允许。1.2.3-beta.4 会被包含,但是 1.2.4-beta.2 会因为元组版号不一致而不被包含。
  • ^0.0.3-beta​ := ​>=0.0.3-beta <0.0.4​ 注意 ​0.0.3​ 先行版本中大于或者等于 ​beta​ 的版本号会被包含. 所以, ​0.0.3-pr.2​ 会被包含.
    在解析 caret ranges 是, 缺失的修订版号会被指定为 0,但当主版本号和次版本号也为 0 是,修订版号可以是任意数值.
  • ​^1.2.x​ := ​>=1.2.0 <2.0.0​
  • ^0.0.x​ := ​>=0.0.0 <0.1.0​
  • ​^0.0​ := ​>=0.0.0 <0.1.0​
    缺失的次版本号和修订版本号会被指定为 0,但可以是任意数值即使主版本也是 0
  • ​^1.x​ := ​>=1.0.0 <2.0.0​
  • ^0.x​ := ​>=0.0.0 <1.0.0​

有什么不对之处,欢迎指正 💐