likes
comments
collection
share

semver库不完全指南

作者站长头像
站长
· 阅读数 3

semver 库用于进行语义化的版本判定

.clean(version)

将传入的版本号尽量清理(整理)为一个符合语义化版本规范的版本号

  1. 若传入的版本号有效会返回正确的版本号,若无效,会返回null
  2. 对于传入的是一个区间(范围)内的版本时无法识别
     semver.clean(' = v 2.1.5foo') // null
     semver.clean(' = v 2.1.5foo', { loose: true }) // '2.1.5-foo' (使用 loose 时判定会宽松一些)
     semver.clean(' = v 2.1.5-foo') // null
     semver.clean(' = v 2.1.5-foo', { loose: true }) // '2.1.5-foo'
     semver.clean('=v2.1.5') // '2.1.5'
     semver.clean(' =v2.1.5') // 2.1.5
     semver.clean(' 2.1.5 ') // '2.1.5'
     semver.clean('~1.0.0') // null

.gt(v1, v2)

判定 v1 > v2 返回 boolean

.gte(v1, v2)

判定 v1 >= v2 返回 boolean

.lt(v1, v2)

判定 v1 < v2 返回 boolean

.lte(v1, v2)

判定 v1 <= v2 返回 boolean

.eq(v1, v2)

判定 v1 == v2 返回 boolean

在某些情况下即使不是完全相等的字符串也可能返回 true 比如 semver.eq("v1.0.0", "1.0.0")) // true,semver.neq("version1.0.0", "1.0.0") 会报版本号无效的类型错误。semver 也做了一些妥协。

neq(v1, v2)

判定 v1 != v2

semver.neq("v1.0.0", "1.0.0") // false

cmp(v1, comparator, v2)

传入一个比较字符串进行版本号对比

  • ===== 不同,像"v1.0.0", "1.0.0" 使用 == 返回 true,=== 返回 false
  • ''=== 相同

semver库不完全指南

compare(v1, v2)

  • v1 == v2 // return 0
  • v1 > v2 // return 1
  • v1 < v2 // return -1

rcompare(v1, v2)

与 compare 恰好相反

  • v1 == v2 // return 0

  • v1 > v2 // return -1

  • v1 < v2 // return 1

diff(v1, v2)

semver.diff('v1.0.0-2.0.0', '1.0.0-2.0.0') // null

semver.diff('v1.0.0-3.0.0', '1.0.0-2.0.0') // prerelease

semver.diff('v2.0.0-2.0.0', '1.0.0-2.0.0') // premajor

semver.diff('v1.1.0-2.0.0', '1.0.0-2.0.0') // preminor

semver.diff('v1.0.1-2.0.0', '1.0.0-2.0.0') // prepatch

semver.diff('v2.0.0', '1.0.0') // major

semver.diff('v1.1.0', '1.0.0') // minor

semver.diff('v1.0.1', '1.0.0') // patch
  • 首先用 compare 判等,若相等则返回 null ,第一个这种范围相等的情况也剔除出去了
  • 范围内前面不等会返回 pre + 不等的部分名称,若相等但是后面不相等一律返回 prerelease
  • Returns difference between two versions by the release type (majorpremajorminorpreminorpatchprepatch, or prerelease), or null if the versions are the same.

什么是语义化版本

语义化版本的出现是为了解决所谓的“dependency hell.”,即随着项目越来越大,功能项越来越多,每一次大的改版会涵盖很多小功能点的更新,而没有明确、语义化的版本定义、明确的文档说明,会让代码维护越来越复杂,到最后成为所谓的“dependency hell.”,因此语义化的版本控制就此应运而生,通常也需要配合详细的版本更新文档,讲明版本更新时增加(减少、修改)了哪些功能点,或者修复了哪些bug。

比如之前在steam上玩一些小公司写的游戏的时候,有时候版本更新只会备注上修改了已知的错误等类似情况,这样会导致一个问题,打补丁的关键开发人员当时对这一补丁很清楚,知道哪里改了,甚至知道改了代码的多少到多少行等等,但是等半年后、一年后在进行项目复盘的时候就会发现,这样的备注简直是灾难,这一点深有感触。

因此语义化版本控制的出现不是单单一个数字化标识,而是需要各方面共同配合,需要详细的文档描述,甚至需要专人来进行文档维护,这在大型项目中是必不可少的,而现在很多小型公司本着能省则省的原则,将这块看似无关紧要的内容省略了来节省成本,反而给项目进展埋下了隐患,导致后期需要付出成倍的人力、物力、财力来填补这个坑,你的领导看到你们在忙,年与时驰意与日去,到最后也只知道你们在忙,项目进度却会越来越慢,矛盾就会滋生,可能这也属于所谓“内耗”的一部分吧。

版本格式意义如下:主版本号.次版本号.修订号,版本号递增规则如下:

  1. 主版本号:做了不兼容的 API 修改,
  2. 次版本号:做了向下兼容的功能性新增,
  3. 修订号:做了向下兼容的问题修正。

先行版本号及版本编译信息可以加到“主版本号.次版本号.修订号”的后面,作为延伸。

更为详细的版本定义规范在这里 语义化版本,下面摘抄几个个人认为比较重要的点:

  1. 使用语义化版本控制的软件必须(MUST)定义公共 API。该 API 可以在代码中被定义或出现于严谨的文档内。无论何种形式都应该力求精确且完整。
  2. 标记版本号的软件发行后,禁止(MUST NOT)改变该版本软件的内容。任何修改都必须(MUST)以新版本发行。
  3. 主版本号为零(0.y.z)的软件处于开发初始阶段,一切都可能随时被改变。这样的公共 API 不应该被视为稳定版。
  4. 先行版本号可以(MAY)被标注在修订版之后,先加上一个连接号再加上一连串以句点分隔的标识符来修饰。标识符必须(MUST)由 ASCII 字母数字和连接号 [0-9A-Za-z-] 组成,且禁止(MUST NOT)留白。数字型的标识符禁止(MUST NOT)在前方补零。先行版的优先级低于相关联的标准版本。被标上先行版本号则表示这个版本并非稳定而且可能无法满足预期的兼容性需求。范例:1.0.0-alpha、1.0.0-alpha.1、1.0.0-0.3.7、1.0.0-x.7.z.92。
  5. 版本的优先层级指的是不同版本在排序时如何比较。
  • 判断优先层级时,必须(MUST)把版本依序拆分为主版本号、次版本号、修订号及先行版本号后进行比较(版本编译信息不在这份比较的列表中)。

  • 由左到右依序比较每个标识符,第一个差异值用来决定优先层级:主版本号、次版本号及修订号以数值比较。

    例如:1.0.0 < 2.0.0 < 2.1.0 < 2.1.1。

  • 当主版本号、次版本号及修订号都相同时,改以优先层级比较低的先行版本号决定。

    例如:1.0.0-alpha < 1.0.0。

  • 有相同主版本号、次版本号及修订号的两个先行版本号,其优先层级必须(MUST)透过由左到右的每个被句点分隔的标识符来比较,直到找到一个差异值后决定:

    a. 只有数字的标识符以数值高低比较。

    b. 有字母或连接号时则逐字以 ASCII 的排序来比较。

    c. 数字的标识符比非数字的标识符优先层级低。

    d. 若开头的标识符都相同时,栏位比较多的先行版本号优先层级比较高。

    例如:1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0。

像“v1.2.3”这样的写法其实并不是一个正规的语义化的版本号。但是,在语义化版本号之前增加前缀 “v” 是用来表示版本号的常用做法。在版本控制系统中,将 “version” 缩写为 “v” 是很常见的。比如:git tag v1.2.3 -m "Release version 1.2.3" 中,“v1.2.3” 表示标签名称,而 “1.2.3” 是语义化版本号。