介绍
前端开发的过程中需要引入一些第三方包,帮助我们快速高效地开发。当第三方包有修改,我们更新包的版本时,我们需要了解包修改的范围,以便对此做出相关反应。
为此,由 Gravatars 创办者兼 GitHub 共同创办者 Tom Preston-Werner 建立了语义化版本控制规范(Semantic Version),表现在 npm 包的版本号中。
单个版本号的构成
结构
major.minor.patch(-prerelease)?
major.minor.patch
- 三者都为自然数;且都以数值来递增。
- 正则表达:
[1-9][0-9]*
prerelease
- 在修订号之后,先加上一个连接号(-)再加上一连串以句号(.)分割的标识符([0-9A-Za-z-])来修饰。
- 数字型的标识符,为自然数
- 正则表达:
-[0-9A-Za-z-](\.[0-9A-Za-z-])*
major(主版本号),minor(次版本号),patch(修订号),prerelease(先行版本号)
major.minor.patch 为标准版本号。
语义说明
- major - 当包源代码修改,修改无法做到向下兼容时,主版本号递增;该修改,可以包含次版本号和修订号的情况。
- minor - 当包源代码修改,新增一些向下兼容的功能,次版本号递增;该修改,可以包含修订号的情况。
- patch - 当包源代码修改,做了向下兼容的问题修改,修订号递增。
- prerelease - 被加上先行版本号表示该版本并非正式版,存在不稳定的情况。
大小比较
标准版本比较:major.minor.patch
- 从左往右,按照数值的大小比较,例如:1.0.0 < 2.0.0 < 2.1.0 < 2.1.1。
先行版本比较:通过先行版本号中,从左往右的每个被句号分开的标识符来比较。
- 只有
数字标识符
比较时,则按数值的大小比较。 - 只有
非数字标识符
比较时,则按照每个标识符
中每个字符
在 ASCII 中的顺序来比较。 数字标识符
和非数字标识符
比较时,则非数字标识符
优先级高。- 若每个标识符都相同的情况,则
标识符层级多
的先行版本号优先级高
。
- 只有
混合比较
- 带有
先行版本号
的版本优先级低于
相关联的标准版本
,例如:1.2.3-beta-1 < 1.2.3
- 带有
版本的顺序
版本号的范围
背景:为了解决在项目中同一个包不同版本的兼容需求,以及安装包时可以升级到预期的最新版本。version 字段可以表达一个版本的范围。
结构
版本范围(version range): (operator version)(joiner(operator version))*
比较器(comparator)结构为:(operator version)
初始操作符
<version
: 小于某个版本<=version
: 小于或等于某个版本>version
: 大于某个版本>=version
: 大于或等于某个版本=version
: 等于某个版本;当没有操作符时,默认为等于(=)操作符,因此该操作符可以不用写。
例如:>=1.2.7
,将匹配1.2.7
、1.2.8
、2.5.3
和1.3.9
,但不会匹配1.2.6
和1.1.0
。
连接符(joiner)
- 空格(whitespace):当比较器由空格连接时,相当于且(&&)。例如,
>=1.2.7 <1.3.0
,将匹配1.2.7
、1.2.8
和1.2.99
,但不会匹配1.2.6
、1.3.0
和1.1.0
。 - || :当比较器由 || 连接时,表示 “或“ 的意义。例如,
1.2.7 || >=1.2.9 <2.0.0
,将匹配1.2.7
、1.2.9
和1.4.6
,但不会匹配1.2.8
和2.0.0
。
与 && 、 || 的优先级一样,空格的优先级高于 || 优先级。
先行版本号的范围
先行版本号的存在表示该版本为非正式版本,存在不稳定的情况。因此带有先行版本号的比较器,其版本覆盖范围有以下两点:
- 正式版本号的范围。
- 正式版本号的先行版本号的范围。
例如: >1.2.3-alpha.3
,相当于 >1.2.3-alpha.3 <1.2.4-0 || >1.2.3
;将匹配 1.2.3-alpha.7
和 3.4.5
,但不会匹配 3.4.5-alpha.9
。
只有标准版本号的范围是无法匹配任何带有先行版本号的版本号,例如:>1.2.3
,将匹配1.2.4
,但不会匹配1.2.4-alpha.9
。
高级版本范围语法
-(Hyphen Ranges)
结构: startVersion - endVersion
相当于 >=startVersion <=endVersion
意义:指定一个版本范围。
例如:1.2.3 - 2.3.4
相当于 >=1.2.3 <=2.3.4
在该语法下,如果版本号的结构中正式版本号部分有缺失,具体处理逻辑为:开始版本号、结束版本号,分别向两端延伸。
例如,开始版本号中的结构有缺失,补 0
处理:
1.2 - 2.3.4
相当于>=1.2.0 <=2.3.4
例如,结束版本号中的结构有缺失,补 X
处理:
1.2.3 - 2.3
相当于1.2.3 - 2.3.x
相当于>=1.2.3 <2.4.0-0
1.2.3 - 2
相当于1.2.3 - 2.x.x
相当于>=1.2.3 <3.0.0-0
X(X-Ranges)
X
、x
、*
在正式版本号中表示为一个数字的占位符,意义为一个自然数。
*
相当于>=0.0.0
(任何版本都满足)1.x
相当于>=1.0.0 <2.0.0-0
(匹配主版本号)1.2.x
相当于>=1.2.0 <1.3.0-0
(匹配次版本号)
版本号中如有缺失部分,也被当作 X
看待,例如:
''
相当于*
1
相当于1.x.x
1.2
相当于1.2.x
~(Tilde Ranges)
具有完整版本号结构的前提下,允许修订号级别的升级变动。
例如:
~1.2.3
相当于>=1.2.3 <1.3.0-0
~1.2.3-beta.2
相当于>=1.2.3-beta.2 <1.3.0-0
其他情况,相当于补 X
。
~1.2
相当于1.2.x
~1
相当于1.x.x
^(Caret Ranges)
具有完整版本号结构的前提下,以标准版本号中最左侧第一个非零元素为界限,允许向后低级别元素的升级变动。
例如:
^1.2.3
相当于>=1.2.3 <2.0.0-0
^0.2.3
相当于>=0.2.3 <0.3.0-0
^0.0.3
相当于>=0.0.3 <0.0.4-0
^1.2.3-beta.2
相当于>=1.2.3-beta.2 <2.0.0-0
其他情况,相当于补 X
。
例如:^0.x
相当于 0.x.x
在正式版本之后,^
符号的版本范围等同于主版本号
不改动,次版本号
和修改号
可以任意升级变动。
修改版本号
npm CLI 提供了编辑和查看 version 的一系列命令。
查看版本号
npm view <pkg> version
:查看某个 pkg latest
标签上的最新版本号。
npm view <pkg> versions
:查看某个 pkg 所有发布过的版本号。
编辑版本号
编辑版本号是通过 npm version
命令来操作的。该命令在修改 package.json - version
的同时,也会自动执行 git commit
保存版本号至 git tag
。因此在操作该命令之前需要保证 git status
是 clear 的。
npm version <newversion>
:newversion 会完全覆盖 package.json - version
的值。
npm version major
:升级主版本号。
npm version minor
:升级次版本号。
npm version patch
:升级修订号。
npm version --preid=<prerelease-id>
:为先行版本号设置一个语义化的前缀。例如,当前版本号为 1.0.1
,执行 npm version --preid=alpha
之后,版本号变为 1.0.2-alpha.0
。
npm version prerelease
:升级先行版本号;例如,当前版本号为 1.0.1-alpha.0
,执行 npm version prerelease
之后,版本号变为 1.0.1-alpha.1
,再执行 npm version prerelease
之后,版本号变为 1.0.1-alpha.2
,以此类推。
最佳实践
开发初始阶段
npm 包的开发初始阶段版本号为:0.a.b
,这一阶段的代码被认为不稳定的,还无法对外公布。
开发阶段的起始版本号可以为:0.0.0
,也可以定为其他版本号, 没有限制。
先行版本号
在开发 npm包
的过程中需要经过一连串的测试环节,通常我们会看到三种类型的 prerelease,分别是:alpha、beta、rc,例如:
1.1.0-alpha.0
1.1.0-beta.0
1.1.0-rc.0
每种类型的 prerelease 都有其特殊的含义:
- alpha - 内测版本,一般为测试环节的第一步;该版本主要给开发人员和测试人员使用的。
- beta - 公测版本,一般为测试环节的第二步;该版本主要给部分公测用户使用的。
- rc(release candidate) - 候选版本,一般为测试环节的第三步;该版本对外公布,并且允许部分或者所有的用户使用;这个版本类似
预览版
或尝鲜版
;该版本已经与正式版本非常接近了 。
在测试过程中,没有必要遵守上面三个测试步骤,开发者可以根据实际需要选择某个 prerelease 作为测试终结版本,并且对外发布相应的正式版本。例如:当
2.0.0-alpha-1
具备发布正式版的条件时,就可以对外发布2.0.0
版本。prerelease 版本号从 0 开始,例如:
1.1.0-alpha.0
正式版本
正式版本发布的条件:初期开发阶段测试结束, npm包
具备对外公布的条件。
第一个正式版本的版本号为:1.0.0
。
从此便开始 npm包
的维护阶段,根据公共 API 及其修改内容更新版本号。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。