npm 版本号和版本控制详解
语义化版本控制
最近在拆分公司的 MonoRepo 仓库, 分割一部分内容成为新的 npm package, 发现公司之前的发布版本控制并不是很规范.
npm 遵循的是语义化版本控制(semantic versioning), 其结构为:
主版本号.次版本号.修订号
三种版本号定义分别是:
- 不兼容的更新
- 向下兼容的功能性更新
- 向下兼容的问题修正
除此以外还可以在修订号后面加上先行版本号(通过-
连接)和版本编译信息(通过+
连接).
例如 1.0.3-rc.1+exp.sha.5114f85
表示:
- 主版本号 1
- 次版本号 0
- 修订号 3
- 先行版本号 rc.1
- 版本编译信息 exp.sha.5114f85
先行版本号
所谓先行版本也就是测试版, 先行版本通常有三种: a
、b
、rc
分别代表alpha(预览版本)
、beta(测试版本)
和release candidate(最终测试版本)
.
先行版后可以跟一个数字, 表示先行版本的迭代, 例如上面的-rc.1
表示最终测试版本 1.
版本编译信息
版本编译信息主要用于跟踪管理不同的构建版本, 属于团队内的约定信息, 并没有什么强制规范.
但是通常包含以下两种:
- 时间戳, 例如
1.0.0+20130313144700
表示构建时间为2013 年 3 月 13 日 14:47:00. - 实验性构建哈希, 例如
exp.sha.5114f85
由两个部分组成, exp 是 experimental 的缩写, 表示实验性. sha.5114f85 则是某次 git 提交的哈希. 由这两个性能我们便可以定位到编译的源代码.
npm包的注意点
除了以上几点, 还要一些约定事项.
版本编译信息不会影响版本
1.0.0+exp.sha.5114f85
和1.0.0+exp.sha.7822af2
虽然编译信息不同, 但是会视作同一个版本, 因此版本编译信息不能发布一个特殊版本的方法.
要为某个客户或者项目提供特供版, 最好的办法是使用先行版本号. 例如1.0.0-customer.1
, 这会被识别为一个新的版本.
新项目的初始版本
新项目的初始版本不是0.0.1
而是0.1.0
.
因为从语义的角度讲, 第三位是修订号.
package.json 中的 dependencies 版本
package.json 可以通过 dependencies 来控制使用的包版本范围
- 补丁发布:1.0 或 1.0.x 或 ~1.0.4
- 次要版本: 1 或 1.x 或 ^1.0.4
- 主要版本发布:* 或 x
例如
"dependencies": {
"lodash": "^1.0.0",
},
在这种配置下, 如果 lodash 发布了 1.1.0, npm 就会拉取这个最新的次要版本.
因为部分开源项目没有遵循上面的规范, 会在次要版本进行 breaking change, 推荐JS项目在稳定运行后进行锁版.