SemVer 语义化版本规范

冬天吃雪糕2022年6月13日
大约 6 分钟

SemVer 语义化版本规范

简介

SemVeropen in new window语义化版本(Semantic Versioning)规范open in new window 的一个实现,目前由 npm 的团队维护,实现了版本和版本范围的解析、计算、比较。

在node项目的package.json中,versiondependenciesdevDependencies等字段中涉及版本的描述,均使用 SemVer 解析。

node-semver 和 semver 的关系

SemVer是一个规范,项目地址是github:semver/semveropen in new window,文档地址是https://semver.org/open in new window

node-semver是由 npm 团队维护的针对 SemVer 规范的一个实现,项目地址是github:npm/node-semveropen in new window,npm包名是semver。因此使用npm install semver命令会安装这个包。

版本号格式

X.Y.Z(主版本号.次版本号.修订号)

版本号递增规则如下:

  1. 主版本号:当你做了不兼容的 API 修改,
  2. 次版本号:当你做了向下兼容的功能性新增,
  3. 修订号:当你做了向下兼容的问题修正。
  • 主版本号、次版本号和修订号为非负整数,且都是递增的。禁止在数字前方补零。
  • 每当主版本号递增时,次版本号和修订号归零;每当次版本号递增时,修订号归零。

先行版本标签

当需要发布并非稳定而且可能无法满足预期的兼容性需求的版本时,可以使用先行版本标签。

先行版本标签被标注在修订号之后,先加上一个连接号(-)再加上一连串以句点(.)分隔的标识符来修饰。标识符可以由英文、数字和连接号([0-9A-Za-z-])组成,不能有空格。

例如:

1.0.0-alpha
1.0.0-alpha.1
1.0.0-0.3.7
1.0.0-x.7.z.92

常见的先行版本标签如下:

  • alpha:内测版,内部交流或者专业测试人员测试用;
  • beta:公测版,专业爱好者大规模测试用,存在一些缺陷,该版本也不适合一般用户安装;
  • gamma:比较成熟的测试版,与即将发行的正式版相差无几;
  • rc:候选版本,处于Gamma阶段,该版本已经完成全部功能并清除大部分的BUG。到了这个阶段只会除BUG,不会对软件做任何大的更改。从Alpha到Beta再到Gamma是改进的先后关系,但RC1、RC2往往是取舍关系。
  • stable:稳定版。在开源软件中,都有 stable 版,这个就是开源软件的稳定发行版。

版本范围

版本范围是一组用于指定满足该范围的版本的比较器。

一个比较器是由操作符和版本号组成。下面是最原始的操作符:

  • <小于;
  • <= 小于等于;
  • > 大于;
  • >= 大于等于;
  • = 等于;如果没有指定操作符,则默认为等于。

一个范围可由一个或者多个比较器组成。当使用空格连接时,表示需要满足这些比较器的交集;当使用双竖线(||)连接时,表示只要满足这些比较器的其一即可。

比如:

对于版本范围>=1.2.7 <1.3.0,版本号1.2.71.2.81.2.99满足条件,而1.2.61.3.01.1.0不满足。

对于版本范围1.2.7 || >=1.2.9 <2.0.0,版本号1.2.71.2.91.4.6满足条件,而1.2.82.0.0不满足。

高级用法

连接符(-)范围X.Y.Z - A.B.C

表示范围的闭包集合

  • 1.2.3 - 2.3.4 := `>=1.2.3 <=2.3.4

如果范围中的第一个版本号只有一部分,剩下的部分以零填充。

  • 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范围1.2.x 1.X 1.2.* *

Xx*表示[主版本号.次版本号.修订号]中的通配符

  • * := >=0.0.0 (任何版本都满足)

  • 1.x := >=1.0.0 <2.0.0 (只要满足主版本号即可)

  • 1.2.x := >=1.2.0 <1.3.0 (需要满足主版本和此版本号)

部分版本号的含义与X范围表示含义一样,所以Xx*都是可以省略的。

  • "" (空字符串) := * := >=0.0.0

  • 1 := 1.x.x := >=1.0.0 <2.0.0

  • 1.2 := 1.2.x := >=1.2.0 <1.3.0

波浪线(~)范围~1.2.3 ~1.2 ~1

不考虑指定版本为部分版本号的情况

表示接受修订更新,即"大于等于指定版本,但不改变主版本号和次版本号。"

~1.2.3,表示安装1.2.x的最新版本(不低于1.2.3),但是不安装1.3.x

大于或等于指定版本。如果指定版本包含次版本号,则表示不允许改变次版本号;如果指定版本不包含次版本号,则表示允许改变次版本号,但不允许改变主版本号。

  • ~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 ^0.2.5 ^0.0.4

不考虑指定版本为部分版本号的情况

表示接受兼容更新,即"大于等于指定版本,但不改变主版本号。"

^1.2.3,表示安装1.x.x的最新版本(不低于1.2.3),但是不安装2.x.x

大于或等于指定版本,不允许改变最左侧的非0版本号。

  • ^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

如果指定的版本号为部分版本号或包含通配符,则剩余部分会用0填充,通配符会转换为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
  • ^1.x := >=1.0.0 <2.0.0
  • ^0.x := >=0.0.0 <1.0.0

先行版本标签与版本范围

如果一个版本号有先行版本标签(例如1.2.3-alpha.3),那么仅当满足以下条件时它会被包含在版本范围中:

  1. 版本范围的指定版本号也有先行版本标签(例如>1.2.3-alpha.3
  2. 该版本号与版本范围中带有先行版本标签的指定版本号有相同的[主版本号.次版本号.修订版本号]
  3. 该版本号的先行版本标签满足版本范围的条件(例如>1.2.3-alpha.3包含1.2.3-alpha.41.2.3-beta,不包含1.2.3-alpha.3

例如:

范围>1.2.3-alpha.3包含版本号1.2.3-alpha.7,但不包含3.4.5-alpha.9。尽管根据 SemVer 的版本号排序规则3.4.5-alpha.9"大于"1.2.3-alpha.3,但是不满足条件2。当然上述范围包含版本3.4.5,因为该版本号没有先行版本标签且大于1.2.3-alpha.3

同理,~1.2.3-beta.2包含1.2.3-beta.4但不包含1.2.4-beta.2,因为该范围等价于>=1.2.3-beta.2 <1.3.0-0

^1.2.3-beta.2包含1.2.3-beta.4但不包含1.2.4-beta.2,因为该范围等价于>=1.2.3-beta.2 <2.0.0-0

上次编辑于: 2022/8/23 06:32:29
贡献者: WingSnow