Bower(和npm)版本语法是什么?

283

Bower使我能够使用以下语法指定软件包的版本要求:

"dependencies": {
  "<name>": "<version>",
},

但是我还没有找到如何使用<version>的语法。我知道可以指定以下版本:

  • 大于某个版本:">1.0.0"
  • 大于或等于某个版本:">=1.0.0"
  • 或在某个范围内:"1.0.0 - 2.0.0"

我也知道有一个常见的版本语法包含波浪号:"~1.0.0"。但我不确定它的意思是否与"=1.0.0"相同。

我还想知道是否可以指定多个非连续版本,例如正好是1.0.3加上大于1.5.0的版本等。


3
可能与此重复:https://dev59.com/emMk5IYBdhLWcg3wvARo#19040351 - David
5个回答

343
简而言之,Bower版本号(以及NPM的)的语法称为SemVer,即“语义化版本控制”,其详细语法文档可在Node/npm中的semver解析器API中找到。您可以在semver.org上了解有关底层规范的更多信息(其中不包括~或其他语法细节)。您可以使用超级方便的视觉semver计算器来轻松理解和测试所有这些内容。
SemVer不仅仅是一个语法!它对于发布API的正确方式有一些非常有趣的观点,这将有助于理解语法的含义。关键在于:
一旦确定了公共API,您就可以通过特定的版本号增量来通知对其进行的更改。考虑到版本格式为X.Y.Z(Major.Minor.Patch)。不影响API的错误修复将增加补丁版本,向后兼容的API添加/更改将增加次要版本,而向后不兼容的API更改将增加主要版本。
因此,关于~的具体问题与Major.Minor.Patch架构有关。 (类似的插入符运算符^也是如此。)您可以使用~来缩小您愿意接受的版本范围,以涵盖以下内容:
- 对于相同的次要版本号,后续补丁级别更改(“不影响API的错误修复”);或者 - 对于相同的主要版本号,后续次要级别更改(“向后兼容的API添加/更改”)
例如:若要表示您将接受1.2.x树上任何后续的补丁级别更改,从1.2.0开始,但小于1.3.0,您可以使用:
"angular": "~1.2"
  or:
"angular": "~1.2.0"

使用这种方式可以得到与使用.x语法相同的结果:

"angular": "1.2.x"

但是,你可以使用波浪线/~语法来更加具体:如果你只想接受补丁级别的更改,从1.2.4开始,但仍小于1.3.0,你应该使用:

"angular": "~1.2.4"

如果你使用的是向左迁移(towards the major version)的版本控制策略……

"angular": "~1"

......它和......是一样的。

"angular": "1.x"
  or:
"angular": "^1.0.0"

......并匹配1.0.0以上的任何次要或补丁级别更改,但小于2.0:

请注意上面的最后一个变化:它被称为'脱字符范围'。插入符号看起来非常像一个>,所以你可能会认为它意味着“任何版本大于 1.0.0”。(我也犯过这样的错误。)但不是!

脱字符范围基本上用于说明您仅关心最左侧的有效数字 - 通常是主要版本 - 并且允许不影响该最左侧数字的任何次要或补丁级别更改。然而,与指定主要版本的波浪线范围不同,脱字符范围允许您指定精确的次要/补丁起始点。因此,尽管^1.0.0 === ~1,但是像^1.2.3这样的脱字符范围可让您说出您将需要任何更改>=1.2.3 && <2.0.0. 您无法使用波浪线范围实现这一点。

一开始所有这些似乎很令人困惑,但请稍微看远一点,这样来考虑:插入符号只是让您说出您最关心的是最左侧的有效数字。波浪线则让您说出您最关心的是最右侧的数字。 其余都是细节。

正是脱字符和波浪线的表达能力解释了为什么人们比简单的.x语法使用它们:它们让您可以做更多事情。这就是为什么你会经常看到波浪线即使在.x可行的情况下也会被使用。例如,请参见npm本身:其自己的package.json文件包含许多以~2.4.0格式的依赖项,而不是2.4.x格式它可以使用。通过坚持使用~,该语法在一个由70多个版本化的依赖项组成的列表中始终保持一致,而不管哪个起始修补程序编号是可接受的。

无论如何,SemVer还有更多内容,但我不会在这里详细介绍。在node semver package's readme上查看它。并且在练习和努力理解SemVer工作原理的同时,一定要使用语义化版本计算器


关于非连续版本号:如果我正确编辑了OP的最后一个问题,那么他似乎是关于指定非连续版本号/范围的。是的,您可以使用常见的双管“或”运算符||来实现这一点。像这样:

"angular": "1.2 <= 1.2.9 || >2.0.0"

27
~ 特指补丁(第三个)数字可以大于指定的数字,例如 ~1.2.3 相当于 >=1.2.3 <1.3.0 - z0r
1
可以用于小版本(第二个数字),根据上面的内联编辑。 - XML
2
x-notation起初很直观易懂,但灵活性不够。例如,'1.1.x' === '>=1.1.0' === '~1.1.0'。在1.1.0这种情况下很容易理解。但是,x-notation不能像'>=1.1.4''~1.1.4'那样具有细粒度。因此,你可能会在依赖列表中的一个地方使用'1.1.x',而在另一个地方使用'~2.7.3'。这没有问题,也可以工作,但开发人员需要解析多个语法才能读取单个列表。如果你正在编写用于以编程方式设置版本的包,你需要一个单一的语法。而且,大多数人都想避免破坏性更改。因此,所有问题都可以通过~解决。 - XML
1
"angular": "~1.2" 不会匹配 1.3、1.4 或 1.4.9。同样,"angular": "~1""angular": "~1.0" 也不等价。请使用 http://semver.npmjs.com/ 进行测试。 - Decima
1
@XML 自从写下那个评论以来,我听到其他澳大利亚人也使用了这个术语。虽然如此,我不认为我会使用它。它太奇怪了。 - Clonkex
显示剩余7条评论

145

根据语义化版本,你可以使用以下方式:

  • 连字符范围 X.Y.Z - A.B.C 1.2.3-2.3.4 表示 >=1.2.3 <=2.3.4

  • X范围 1.2.x 1.X 1.2.*

  • 波浪线范围 ~1.2.3 ~1.2 允许修补级别和次要版本的更改。

  • 插入符范围 ^1.2.3 ^0.2.5 ^0.0.4

    允许不修改[major、minor、patch]元组中最左侧的非零数字的变化。

    • ^1.2.x (表示 >=1.2.0 <2.0.0)
    • ^0.0.x (表示 >=0.0.0 <0.1.0)
    • ^0.0 (表示 >=0.0.0 <0.1.0)

21
谢谢你的简明易懂的回答,不需要再去查找或其他操作,就像“砰”的一声,答案就摆在那里了。干得好 ;) - toddmo

76
Bower使用semver语法,以下是一些快速示例:
您可以安装特定版本:

You can install the latest version:


您可以安装最新版本:
$ bower install jquery#1.11.1

您可以使用 ~ 来指定“以此开头的任何版本”:
$ bower install jquery#~1.11

您可以一起指定多个版本要求:
$ bower install "jquery#<2.0 >1.10"

1
我对这个的实际用途很好奇。轮盘安装? - gravidThoughts
看@XMLilley的回答(以及semver文档),'start's with'似乎是错误的,因为1.12、1.13也可以,只要主版本不增加... - Frank N

13

您也可以使用 latest 关键字安装最新版本:

  "dependencies": {
    "fontawesome": "latest"
  }

1
semver 没有提到这一点。你是在哪里确认它是有效的呢? :) 它确实说 ""*" := >=0.0.0(任何版本都可以满足),但这有点模糊,因为它没有明确指出最新版本,所以它可能是找到的第一个版本? - GazB
说实话,这只是试错法 - 我尝试了一下,结果有效!你可能是对的,它可能不是100%有效,但确实能用。 - shacker

7
如果没有补丁号,~ 相当于将非波浪线版本追加 .x。如果有补丁号,~ 表示允许所有大于等于指定补丁号的补丁。
~1     := 1.x
~1.2   := 1.2.x
~1.2.3 := (>=1.2.3 <1.3.0)

我没有足够的积分来评论被接受的答案,但是一些波浪号(tilde)信息与链接的semver文档不符合:"angular": "~1.2"不会匹配1.3、1.4或1.4.9。此外,"angular": "~1""angular": "~1.0"等同。可以使用npm semver计算器验证这一点。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接