聊聊 npm 的语义化版本(Semver) · Issue #312 · mqyqingfeng/Blog
所以由 Gravatars 创办者兼 GitHub 共同创办者 Tom Preston-Werner 就建立了语义化版本控制的规范, semantic version
简称 semver
,于是这个规范就叫做 SemVer 规范,规范地址为:https://semver.org/lang/zh-CN/
版本号的格式
标准的版本号必须采用 X.Y.Z 的格式,其中 X、Y 和 Z 为非负的整数,且禁止在数字前方补零。X 是主版本号、Y 是次版本号、而 Z 为修订号,英文对应表示为 major、minor、patch,每个元素必须以数值来递增。例如:1.9.1 -> 1.10.0 -> 1.11.0。
主版本号为零(0.y.z)的软件处于开发初始阶段,一切都可能随时被改变。
1.0.0 的版本号用于界定公共 API 的形成。
版本号的递增逻辑
修订号 Z(x.y.Z | x > 0): 修改BUG时新增。向下兼容。
次版本号 Y(x.Y.z | x > 0): 必须在有向下兼容的新功能出现时递增。在任何公共 API 的功能被标记为弃用时也必须递增。也可以在内部程序有大量新功能或改进被加入时递增,其中可以包括修订级别的改变。每当次版本号递增时,修订号必须归零。
主版本号 X(X.y.z | X > 0)必须在有任何不兼容的修改被加入公共 API 时递增。其中可以包括次版本号及修订级别的改变。每当主版本号递增时,次版本号和修订号必须归零。
简单的总结下就是:
- 当有不兼容的 API 更改时,则升级主版本号
- 当以向后兼容的方式添加功能时,则升级次版本号
- 当进行向后兼容的缺陷修复时,则升级修订号
关于先行版本
先行版本号可以被标注在修订版之后,先加上一个连接号再加上一连串以句点分隔的标识符来修饰。标识符必须由 ASCII 字母数字和连接号组成,且禁止留白。数字型的标识符禁止在前方补零,举个例子:1.0.0-alpha.6
先行版的优先级低于相关联的标准版本,举个例子 1.0.0-alpha < 1.0.0
被标上先行版本号则表示这个版本并非稳定而且可能无法满足预期的兼容性需求。
alpha beta 和 rc
现在我们知道,先行版本中 -
后的字符是自定义的,我们经常看到一些库的版本会带 alpha、beta 之类的字样,就以 Vue 为例,有 3.0.0-alpha.13
、3.0.0-beta.1
、3.0.0-rc.1
,这些表示什么意思呢?
一般来说:
alpha 表示内部测试版,主要给开发和测试找 bug 用,不建议用户下载
beta 表示公开测试版,你可以提前尝试一些功能
rc 是 Release Candidate(候选版本)的缩写,表示该版本功能不再增加,和最终发布版功能一样,有点像预览版,然后可能再改改一些小 bug,就会到正式的版本了。
当然库也可以使用自己的版本逻辑,就比如 React,它还有 next 版和 experimental 版,具体的发布逻辑 React 官网也有写: https://react.docschina.org/docs/release-channels.html
npm 指定版本范围
这些标识符的作用相信我们多少都知道一点,比如:
^
表示次版本号的更新,比如 ^1.2.3
就表示以后安装的版本 >=1.2.3 <2.0.0
~
表示修订版本号的更新,比如 ~1.2.3
就表示以后安装的版本 >=1.2.3 <1.3.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
,这其中1.2.3-beta.4
是可以的,但1.2.4-beta.2
就不行了
~
如果指定了次版本号,则会只进行修订版本号的更新,如果没有指定,则会进行此版本号的更新,所以:
~1.2.3
相当于>=1.2.3 <1.3.0
~1.2
相当于>=1.2.0 <1.3.0
(相当于 1.2.x)~1
相当于>=1.0.0 <2.0.0
(相当于 1.x)~1.2.3-beta.2
相当于>=1.2.3-beta.2 <1.3.0
,这其中1.2.3-beta.4
是可以的,但1.2.4-beta.2
就不行了
除了 ^
和 ~
,NPM 提供了更多的表示范围版本的方式:https://docs.npmjs.com/cli/v8/configuring-npm/package-json#dependencies