当预发布版本是最新可用版本时,semver 中的插入符 (^) 是否与预发布匹配?

Does caret (^) in semver matches pre-release when pre-release version is the latest available version?

考虑使用这些版本的库(例如 NPM 包):

如果我在依赖项中指定 ^1.0.0,将安装什么版本? 1.1.0-prerelease 是最新版本,但我认为没有任何预发布版本满足我未指定预发布部分的范围。我试过使用 https://semver.npmjs.com,但是 lodash 没有预发布也是最新的情况。

通常带有脱字符号(^)前缀的范围,例如^1.0.0 不会导致正在安装预发布版本 1.1.0-prerelease

因此,根据您问题中提供的示例,通常 安装的版本是 1.0.2

注意:然而,这种逻辑可能并不总是如此——我稍后会解释原因。


使用 Semver 计算器的 典型 逻辑示例:

在撰写本文时,使用 Semver 计算器说明 典型 逻辑的更好示例是使用 typescript 而不是 lodash 进行测试。

使用 semver calculator:

  1. 选择typescript作为包裹
  2. 输入范围^4.0.0

如您所见,selects 4.0.2 而不是 select 4.2.0-dev.20201204(在 4.0.2 之后发布到 npm 注册表)。这个逻辑是通常会发生什么。

上述典型逻辑何时可能不同:

您会注意到,在我之前的解释中,我经常说 “通常”。我这么说是因为 npm 有一个 dist-tag 特性,允许包的发布者修改分发标签。 dist-tag 文档的简短摘录如下:

By default, the latest tag is used by npm to identify the current version of a package, and npm install <pkg> (without any @<version> or @<tag> specifier) installs the latest tag. Typically, projects only use the latest tag for stable release versions, and use other tags for unstable versions such as prereleases.

因此,如果我们再次考虑上一节中描述的 typescript 示例。如果发布者将 npm 注册表中的 latest 标记与版本 4.2.0-dev.20201204 相关联。例如,如果他们 运行 以下命令:

npm dist-tag add typescript@4.2.0-dev.20201204 latest

那么版本 4.0.2 将不会被安装 (给定 semver 范围 ^4.0.0),而是版本 4.2.0-dev.20201204 将被安装.

同样,鉴于您的问题中提供的示例,如果我们要将 latest 标记与版本 1.1.0-prerelease 相关联(使用 npm dist-tag ... 命令),并指定一个范围如 ^1.0.0package.jsondependencies 部分,那么将安装版本 1.1.0-prerelease 而不是 1.0.2

注意:我认为本节中描述的这些场景非常罕见(它们当然不典型但有助于理解),因为如前一段摘录所述来自文档:

Typically, projects only use the latest tag for stable release versions


附加信息:

使用 npm view 命令来发现有关包 dist 标签的信息,尤其是 latest 标签。例如:

  • 以下命令打印 typescript 包的所有标记信息:

    npm view typescript dist-tags
    
  • 以下命令打印与 typescript 包的 latest 标签关联的版本:

    npm view typescript dist-tags.latest
    

有关分发标签的更多信息,请参阅 adding dist-tags to packages