最近semver比较火爆,很多人喜欢标榜遵从使用semver而彰显自己的在版本管理上的专业性。
这当然是好事,但是很遗憾,semver的规范还是有问题的。
先说说npm包的常见问题
首先对于npm来说,版本经常出问题的原因是npm的自动升级。
由于npm默认子版本是兼容性的升级,所以当你的package.json标记成兼容升级后就会自动下载最新的版本安装。而不是你当时测试的版本安装,从而导致了包的不稳定。
比如你的package.json里安装了xxx的包。
格式是:
xxx: '^1.1.1'
而作者
最近发布了^1.2.1
,
但是作者没有遵守npm的约定,将升级的版本做兼容处理。
这样你的包由于默认自动升级,所以你的包只要重新安装就会运行失败。
而这个是npm包的升级范围造成的问题。
所以我认为npm的升级范围是万恶之源,所以推荐大家使用包的时候使用没有范围的精确形式。
通常可以使用
npm install --save-exact xxx
保存你使用的版本。
再说说semver的问题
由于npm存在的问题, semver的发布试图去规范版本的发布问题。但是似乎又走了极端。
semver要求子版本不能做不兼容的修改,这是非常不现实的。
我们知道在开发过程中,最好的当然是一开始就预测所有的事情。
这也是原来瀑布模型的思路。
但是很遗憾,人类总是不能对未来做100%预测的。
所以如果你着手准备一个版本时,除了特别简单的软件,100%的情况你的软件的API是会变动的。
所以minor版本不变的思路是不实际的。
相反的如果:
将主版本(Major version)看成是架构的调整, 次版本(Minor version)看成是功能的调整,
那么semver就比较有价值了。
所以我在semver的github上提了一下我的看法:
https://github.com/mojombo/semver/issues/365
根本问题
在这个issue里,我认为导致软件不稳定的根本原因是npm定义了默认的升级范围,并且默认是子版本范围的。 如果将范围调整成是PATCH,问题就会少很多。
所以我认为semver的错误根源在于npm的错误。默认子版本范围内的变动是兼容变动。
小结
semver是一次版本管理的规范尝试,由于semver是基于npm的,天然的基因是存在问题的。因为npm的默认安全range是子版本,所以会导致版本过份增长的情况。
从而导致了软件版本将无法反应它的功能升级,是一次新的极端,不太建议跟进。
建议的做法是:
- 主版本表示主功能或者架构的重大调整
- 次版本表示小功能的增加或者修正
- 补丁用于兼容性的bugfix