package版本号知多少

442 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

使用npmyarn安装package的时候,版本号前面通常附带有^ ~的符号,这些符号有什么含义呢?

版本号

版本号的概念在semver2.0.0版本的文档中有详细描述,开头的=v会被处理掉并且忽略。

版本号格式是遵循semver规定的,版本格式为:

主版本号.次版本号.修订号-版本后缀,版本后缀不是必须的,用于记录先行版本号或版本的编译信息。

版本号来记录软件发版迭代版本,版本号通常包含3段,用.隔开,比如a.b.c

a表示大版本号,一般当软件整体重写,或出现不向后兼容的改变是,从a上递增,a0表示软件还在开发阶段

b表示功能更新,推出新功能时增加b

c表示小修改,比如修复bug,只要有修改,c就会增加

版本号后缀就是除了以上提到的版本号包括a.b.c3段之外的修饰词,比如:

alpha:内部版本

beta:测试版

rc:即将作为正式版发布

lts:长期维护的版本

举个例子

Ant Design是前端常用的UI组件库,就用它来举例。

进入Ant Design的官网,就能在顶部看到当前组件库的版本号,右侧的RTL代表当前版本是长期维护版本

版本列表中罗列是不同的迭代版本,当前正在迭代的版本是4.x

版本号范围

版本范围是一组比较器的集合,它能指定满足范围的版本

  • 由空格间隔的比较器集合之间取交集,比如>=1.2.7 <1.3.0,要求版本号范围在[1.2.7, 1.3.0)左闭右开范围内;

  • ||连接的比较器,版本号要在其中任何一个||连接的范围内,比如1.2.7 || >=1.2.9 <2.0.01.2.7或在[1.2.9, 2.0.0)之间的版本号是符合要求的,1.2.8, 2.0.0都不符合要求

符号描述
~version约等于版本
^version兼容版本
version必须匹配当前版本
>version高于该版本
>=version高于或等于该版本
<version低于该版本
<=version低于或等于该版本
2.3.x2.3.0, 2.3.1等等,但是不会达到2.4.0
*任意版本
latest包含最新版本

预发布版本号-alpha

如果一个版本有一个预发布标签(例如,1.2.3-alpha.3),那么只有当至少一个具有相同元组[major, minor, patch]的比较器也有一个预发布标签时,它才被允许满足比较器集。

比如>2.1.3-alpha.3能够符合2.1.3-alpha.7,但是不符合3.4.5-alpha.8,即使3.4.5>2.1.3-alpha.3。版本范围只能接受2.1.3版本的预发布版本。3.4.5是符合的,因为它没有预发布标签,而且高于2.1.3-alpha.3

为什么会对预发布标签有这样的要求呢?

  1. 预发布版本变动频繁且快速,并且有很多意料之外的重要改变(breaking change),所以在版本匹配的时候不包括预发布版本

  2. 选择使用预发布版本的用户已经清楚地表明了使用该特定的alpha/beta/rc版本集的意图。通过在范围中包含预发布标记,用户表明他们意识到了风险。然而,假设他们已经选择在下一套预发行版本中承担类似的风险仍然是不合适的。

    请注意,可以通过在选项对象上为任何进行范围匹配的函数设置includePrerrelease标志来抑制这种行为(为了范围匹配的目的,将所有预发布版本视为普通版本)。

    semver for npm中的所有方法和类都接收options对象作为最后一个参数,默认为false。通过设置options中的includePrerelease参数,可以抑制从范围中排除预发布版本的默认行为,除非它们被明确选择加入。

令人费解的^~

  • 插入符号^表示与版本兼容。

    ^符号允许不改变[主版本号.次版本号.修订版本号]元组中最左侧非零元素的修改。阳间解释就是说允许版本号>=1.0.0的版本更新次版本号或修订版本号,版本号0.X>=0.1.0的版本更新修订版本号,版本号为0.0.X的话,则不允许更新为更高版本。

    ^保证[主版本号.次版本号.修订版本号]元组中的最左侧非零元素不发生变化。

    很多人将0.x中的x视为功能主要的**重要改变**的指示器。当需要在0.2.40.3.0版本之间有重要功能(breaking change)改变时,使用^指示范围是合理的。然而,人们通常认为在0.2.40.2.5之间不会发生重要功能的修改,只会有一些补充性的功能修复。

    版本号范围
    ^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注意这里的预发布版本的更新规则:只允许更新为1.2.3版本中>=beta.2的预发布版本,1.2.4-beta.2则是不允许的,因为版本号对应的元组不同了

    ^限制的版本号范围中,缺失的修订号降低为0,但是可以灵活变化,即使主版本号和次版本号都为0。

    版本号范围
    ^1.2.x>=1.2.0 <2.0.0-0
    ^0.0.x>=0.0.0 <0.1.0-0
    ^0.x>=0.0.0 <0.1.0-0

    缺失的次版本号修订号同样降低为0,但是可以灵活变化,即使主版本号为0

    版本号范围
    ^1.x>=1.0.0 <2.0.0-0
    ^0.x>=0.0.0 <0.1.0-0
  • ~表示约等于版本。

    波浪线~的限制规则为:如果比较器中存在次版本号,那么按照修订号更新;否则就改变次版本号

    版本号范围等价于
    ~1.2.3>=1.2.3 <1.3.0-0
    ~1.2>=1.2.0 <1.3.0-01.2.x
    ~1>=1.0.0 <2.0.01.x
    ~0.2.3>=0.2.3 <0.3.0-0
    ~0.2>0.2.0 <0.3.0-00.2.x
    ~0>0.0.0 <1.0.0-00.x
    ~1.2.3-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.4-beta.2是另一个元组[主版本号.次版本号.修订版本号]的预发布版本了

    总结下来就是说~a这种只存在主版本号的比较器,限制范围为~a.x~b.c格式的比较器,限制范围为~b.c.x;另外如果比较器中存在预发布版本号,则预发布版本号也可更新为符合[主版本号.次版本号.修订版本号]元组限制的预发布版本号

参考链接

semver-语义化版本

package.json中的版本号

package.json指南

Why is there a caret(^) in my package.json?

stackoverflow

semver for npm-github

semver的使用场景