波浪号(~)和插入符号(^)的区别是package.json?

在我升级到最新的稳定nodenpm后,我尝试了npm install moment --save。它使用插入符号^前缀保存package.json中的条目。以前,它是波浪号~前缀。

  1. 为什么在npm中进行这些更改?
  2. 波浪号~和插入符号^有什么区别?
  3. 与其他人相比有什么优势?
1414838 次浏览

请参阅NPM文档semver docs

  • ~version“大致相当于版本”,将更新您到所有未来的补丁版本,而不增加次要版本。~1.2.3将使用从1.2.3到<1.3.0的版本。

  • ^version“与版本兼容”,将更新您到所有未来的次要/补丁版本,而不增加主要版本。^2.3.4将使用2.3.4到<3.0.0的版本。

请参阅下面的评论以了解例外情况,特别是对于前一个版本,例如^0.2.3

只要第一个数字(“主要”)至少为1:

~锁定主要和次要数字。当您准备好只接受bug修复(第三个数字中的增量),但不希望任何其他更改,甚至不希望添加功能的次要升级时,就会使用它。

^仅锁定主要数字。当您愿意接收bug修复(第三个数字中的增量)和次要升级(添加功能但不应该破坏现有代码(第二个数字中的增量))时使用它。但是,您不希望更改破坏现有代码(第一个数字中的增量)。

除此之外,^在旧的npm版本中是不支持,应该谨慎使用。

所以,^是一个很好的默认值,但它并不完美。我建议仔细选择和配置对您最有用的semver运算符。

(修改以避免说“修复”和“bug修复”与“修复”的冲突使用,这令人困惑)

~:合理地关闭

   ~1.1.5: 1.1.0 <= accepted < 1.2.0

^兼容

   ^1.1.5: 1.1.5 <= accepted < 2.0.0
^0.1.3: 0.1.3 <= accepted < 0.2.0
^0.0.4: 0.0.4 <= accepted < 0.1.0

我想添加官方的npmjs留档,它描述了版本特异性的所有方法,包括问题中提到的方法

desc
~version大约相当于版本,即只接受新的补丁版本
npm semver-Tilde Ranges
^version与版本兼容,即接受新的小调和补丁版本
参见npm semver-Caret Ranges
version必须完全匹配版本
>version必须大于版本
>=version
<version
<=version
1.2.x1.2.0、1.2.1等等,但不是1.3.0
*匹配任何版本
latest获得最新版本

上面的列表并不详尽。其他版本说明符包括GitHub URL和GitHub用户存储库、本地路径和具有特定npm标签的包

官方文档

^是1.[any].[any](最新次要版本)
~是1.2。[任何](最新补丁)

一个很好的阅读是这篇博客文章关于semver如何应用于npm
以及他们正在做什么使其匹配Semver标准
http://blog.npmjs.org/post/98131109725/npm-2-0-0

npm允许安装比指定版本更新的包。使用波浪号(~)可以为您提供bug修复版本,插入符号(^)也可以为您提供向后兼容的新功能。

问题是旧版本通常不会收到那么多bug修复,所以npm使用插入符号(^)作为--save的默认值。

semver table

根据:“Semver解释说-为什么我的package.json?中有一个插入符号(^)

说明表示规则适用于1.0.0以上的版本,并且并非每个项目都遵循语义版本控制。对于版本0. x. x,插入符号只允许补丁更新,即它的行为与波浪号相同。见“卡尔特范围”

以下是对概念的可视化解释:

semver图

来源:“语义版本控制备忘单”

Semver

<major>.<minor>.<patch>-beta.<beta> == 1.2.3-beta.2
  • 使用npm semver计算器进行测试。虽然^(包括在同一主要范围内大于特定版本的所有内容)和~(包括在同一次要范围内大于特定版本的所有内容)的解释不是100%正确,但计算器似乎可以正常工作。
  • 或者,使用SemVer检查代替,这不需要您选择一个包,并且还提供解释。

允许或不允许更改

  • 引脚版本:1.2.3
  • 使用^(如head)。允许在左侧第二个非零级别进行更新:^0.2.3表示0.2.3 <= v < 0.3
  • 使用~(如尾部)。如果省略,通常冻结最右边的级别或设置零:
  • ~1表示1.0.0 <= v < 2.0.0
  • ~1.2表示1.2.0 <= v < 1.3.0
  • ~1.2.4表示1.2.4 <= v < 1.3.0
  • 省略最右边的级别:0.2表示0.2 <= v < 1。与~不同,因为:
    • 开始省略级别版本始终为0
    • 您可以在不指定子级别的情况下设置起始主要版本。

所有(希望)的可能性

设置开始主要级别并允许向上更新

*  or "(empty string)   any version1                         v >= 1

冻结主要职等

~0 (0)            0.0 <= v < 10.2               0.2 <= v < 1          // Can't do that with ^ or ~~1 (1, ^1)        1 <= v < 2^1.2              1.2 <= v < 2^1.2.3            1.2.3 <= v < 2^1.2.3-beta.4     1.2.3-beta.4 <= v < 2

冻结小级别

^0.0 (0.0)        0 <= v < 0.1~0.2              0.2 <= v < 0.3~1.2              1.2 <= v < 1.3~0.2.3 (^0.2.3)   0.2.3 <= v < 0.3~1.2.3            1.2.3 <= v < 1.3

冻结补丁级别

~1.2.3-beta.4     1.2.3-beta.4 <= v < 1.2.4 (only beta or pr allowed)^0.0.3-beta       0.0.3-beta.0 <= v < 0.0.4 or 0.0.3-pr.0 <= v < 0.0.4 (only beta or pr allowed)^0.0.3-beta.4     0.0.3-beta.4 <= v < 0.0.4 or 0.0.3-pr.4 <= v < 0.0.4 (only beta or pr allowed)

禁止更新

1.2.3             1.2.3^0.0.3 (0.0.3)    0.0.3

公告:缺少主要,次要,补丁或指定beta而没有数字,与缺少级别的any相同。

公告:当你安装一个包,其中0作为主要级别,更新将只安装新的beta/pr级别的版本!这是因为npm设置^作为默认的package.json和当安装的版本是0.1.3,它冻结所有主要/次要/补丁级别。

帽子匹配可能被认为是“损坏的”,因为它不会将^0.1.2更新到0.2.0。当软件出现时,使用0.x.y版本,帽子匹配只会匹配最后一个变化的数字(y)。这是故意的。原因是当软件发展时,API会迅速变化:有一天你有这些方法,另一天你有这些方法,旧的方法就消失了。如果你不想为已经在使用你的库的人打破代码,你可以递增主要版本:例如1.0.0->2.0.0->3.0.0。所以,当你的软件最终100%完成并功能齐全时,它将像版本11.0.0,这看起来不是很有意义,实际上看起来很混乱。另一方面,如果你使用0.1.x->0.2.x->0.2.00版本,那么当软件最终100%完成并功能齐全时,它将作为版本1.0.0发布,这意味着“此版本是一个长期服务版本,您可以在生产代码中继续使用此版本的库,作者不会在明天或下个月更改所有内容,他也不会放弃包”。

规则是:当你的软件尚未成熟时使用0.x.y版本控制,当你的公共API发生变化时增加中间位数(因此^0.1.0的人不会得到0.2.0更新,也不会破坏他们的代码)。然后,当软件成熟时,在1.0.0下发布它,并在每次你的公共API发生变化时增加最左边的数字(因此^1.0.0的人不会得到2.0.0更新,也不会破坏他们的代码)。

Given a version number MAJOR.MINOR.PATCH, increment the:
MAJOR version when you make incompatible API changes,MINOR version when you add functionality in a backwards-compatible manner, andPATCH version when you make backwards-compatible bug fixes.

~波浪:

  • ~冻结主要和次要数字。
  • 当您准备接受依赖项中的bug修复时使用它,但不希望任何可能不兼容的更改。
  • 波浪号匹配最新次要版本(中间数字)。
  • ~1.2.3将匹配所有1.2. x版本,但它将错过1.3.0。
  • Tilde(~)为您提供bug修复版本

^Caret:

  • ^只冻结主要数字。
  • 当您密切关注依赖项并准备好在次要版本不兼容时快速更改代码时使用它。
  • 它会将您更新为最新主要版本(第一个数字)。
  • ^1.2.3将匹配包括1.3.0在内的任何1. x. x版本,但它将在2.0.0上保持不变。
  • Caret(^)还为您提供向后兼容的新功能。

一个线性解释

标准版本控制系统major.minor.build(例如2.4.1)

npm根据这些字符检查并修复特定包的版本

~:主要版本是固定的,次要版本是固定的,匹配任何版本号

例如:~2.4.1意味着它将检查2.4. x,其中x是任何东西

^:主要版本是固定的,匹配任何次要版本,匹配任何版本号

例如:^2.4.1表示它将检查2. x. x,其中x是任何东西

您可能已经看到波浪号(~)和插入符号(^)在package.json.它们之间有什么区别?

当你做npm安装时刻--保存时,它会将条目保存在带有插入符号(^)前缀的package.json中。

波浪(~)

最简单地说,波浪号(~)匹配最近的次要版本(中间数字)。~1.2.3将匹配所有1.2. x版本,但将错过1.3.0。

插入符号(^)

另一方面,插入符号(^)更宽松。它会将您更新到最新的主要版本(第一个数字)。^1.2.3将匹配包括1.3.0在内的任何1. x. x版本,但将在2.0.0上暂停。

参考:https://medium.com/@Hardy2151347b

波浪(~)

主要版本是固定的,次要版本是固定的,匹配任何构建数字

"express": "~4.13.3"

~4.13.3表示它将检查4.13. x,其中x是任何东西

卡尔特(^)

主要版本是固定的,匹配任何次要版本,匹配任何构建数字

"supertest": "^3.0.0"

^3.0.0表示它将检查3. x. x,其中x是任何东西

Tilde~指定次要版本版本

Caret^指定主要版本版本

例如,如果包版本为4.5.2,则在更新时:

~4.5.2将安装最新的4.5.x version (MINOR VERSION)

^4.5.2将安装最新的4.x.x version (MAJOR VERSION)

版本号在语法中,它指定每个部分具有不同的含义。语法被分成三个由点分隔的部分。

major.minor.patch1.0.2

主要、次要和补丁代表包的不同版本。

npm使用波浪号(~)和插入符号(^)分别指定要使用的补丁和次要版本。

因此,如果您看到~1.0.2,则意味着安装版本1.0.2或最新的补丁版本,例如1.0.4。如果您看到^1.0.2,则意味着安装版本1.0.2或最新的次要或补丁版本,例如1.1.0。

Tilde~匹配次要版本,如果您安装了一个具有1.4.2的包,并且在安装后,版本1.4.3和1.4.4也可用,如果在您的package.json中它被用作~1.4.2,那么升级后的npm install在您的项目中将在您的项目中安装1.4.4。但是该包有1.5.0可用,那么它将不会被~安装。它被称为次要版本。

Caret^匹配主要版本,如果您的项目中安装了1.4.2包,并且在您的安装1.5.0发布后,^将安装主要版本。如果您有^1.4.2,它将不允许安装2.1.0。

修复版本如果您不想在每次安装时更改包的版本,则使用固定版本,没有任何特殊字符,例如"1.4.2"

最新版本*如果您想安装最新版本,请仅在包名前使用*。

这本身不是答案,而是一个似乎被忽视的观察。

插入符号范围的描述:

见:https://github.com/npm/node-semver#caret-ranges-123-025-004

允许不修改最左边的非零数字的更改[主要,次要,补丁]元组。

表示^10.2.3匹配10.2.3 <= v < 20.0.0

我不认为这是他们的意思。拉入11. x. x到19. x. x版本会破坏您的代码。

我想他们的意思是left most non-zero number field。SemVer中没有任何东西要求数字字段必须是个位数。

插入符号^包括在同一主要范围内大于特定版本的所有内容。

波浪号~包括在同一次要范围内大于特定版本的所有内容。

例如,要指定高达1.0.4的可接受版本范围,请使用以下语法:

  • 补丁版本:1.0或1.0. x或~1.0.4
  • 次要版本:1或1. x或^1.0.4
  • 主要版本:*或x

有关语义版本控制语法的更多信息,请参阅npm semver计算器

npm语义版本在已发布的包中§

更多npm留档关于语义版本控制

Semver分为3个主要部分,由点打破。

major.minor.patch1.0.0

这些不同的主要,次要和补丁用于识别不同的版本。

~1.0.1Install 1.0.1 or **latest patch versions** such as 1.0.2 ,1.0.5^1.0.1Install 1.0.1 or **latest patch and minor versions** such as 1.0.2 ,1.1.0 ,1.1.1

关于这个问题,你可以回顾Composer留档版本,但在这里简而言之:

  • 波浪版本范围(~)-~1.2.3等价于>=1.2.3<1.3.0
  • 插入符号版本范围(^)-~1.2.3等价于>=1.2.3<2.0.0

因此,使用Tilde,您将获得补丁的自动更新,但次要和主要版本不会更新。但是,如果您使用Caret,您将获得补丁和次要版本,但您不会获得主要(重大更改)版本。

Tilde版本被认为是“更安全”的方法,但如果您使用的是可靠的依赖项(维护良好的库),那么您应该不会对Caret版本有任何问题(因为微小的更改不应该破坏更改。

您可能需要查看这篇stackoverflow文章介绍了作曲家安装和作曲家更新之间的区别