不喜欢广告? 无广告 今天

语义化版本控制 package.json 中数字的实际含义

更新于

每个 package.json 文件都包含版本字符串,但大多数开发者只是信任 caret(^)符号而不知道它允许什么。本指南将解释 MAJOR.MINOR.PATCH 协议,以及 ^、~、>= 和 * 符号分别会接受哪些更新。

每个 package.json 都有版本字符串,但大多数开发者只是信任 caret 而不知道它允许什么。本指南解释了 MAJOR.MINOR.PATCH 协议,以及 ^、~、>= 和 * 操作符将接受哪些更新。
广告 移除?

每个 JavaScript 项目都有一个 package.json。大多数开发者已经输入过数百次,却从未真正思考过版本字符串的含义。但如果你问他们 npm install some-library 实际上允许什么——也就是说,npm 会乐意拉取哪些版本——他们通常只会耸耸肩。 ^1.2.3 这并不是一个微不足道的差距。一个误解的版本范围,会导致一个原本在新机器上运行正常的 CI 流水线突然中断,而这个流水线在几个月前是完全正常的。理解这些数字背后的协议,是那些投入少、回报高的事,它能区分那些几分钟内就能调试版本问题的开发者,和那些花费数小时才解决的开发者。

MAJOR.MINOR.PATCH 协议 npm install 语义化版本控制(semver)是一种三数字格式:

每个位置都承载着关于变更的具体承诺:

MAJOR MAJOR.MINOR.PATCH——破坏性变更。升级到一个主要版本可能需要你更新代码。

  • MINOR ——新增功能,向后兼容。你的现有代码应继续正常运行。
  • ——仅修复错误。安全升级,无需 API 变更。 这就是
  • PATCH 协议

包发布所遵循的。从 升级到 应添加新功能而不破坏现有行为。升级到 2.3.12.4.0 是你的警告信号:升级前请务必查看变更日志。 3.0.0 在实践中,维护者有时会不小心在次要版本中引入破坏性变更。语义化版本控制并不强制执行——它只是一个约定。但它为你提供了一个评估风险的框架,而所有版本范围操作符都是基于这个框架构建的。

什么构成破坏性变更?

破坏性变更是指任何迫使消费者更新其代码的情况:

移除或重命名导出的函数、类或常量

  • 改变函数的签名——移除参数、添加必需参数或改变返回类型
  • 以一种导致调用代码行为错误的方式改变可观察行为
  • 以不兼容的方式改变配置文件格式
  • 添加一个新可选参数?那是 MINOR。添加一个新导出?那是 MINOR。修复一个有人错误地将其当作功能依赖的 bug?这需要判断,但通常归为 PATCH。如有疑问,请提升 MINOR 并清晰地记录说明。

package.json 中的版本范围操作符

打开任何

,你都会看到类似 package.json 的版本字符串。这些不是精确的固定值——它们是 "^4.17.21""~1.0.4"范围 ,告诉 npm 或 yarn 在解析依赖树时可以接受哪些版本。 caret ^ —— 兼容版本

当运行

时,caret 是默认操作符。它表示:“接受任何不改变最左侧非零数字的版本。”在实践中,对于稳定包来说,这意味着相同主要版本,任意次要或补丁版本: npm install零主要版本的行为是故意设计的。位于

^1.2.3  →  >=1.2.3 <2.0.0   (any 1.x.x at or above 1.2.3)
^0.2.3  →  >=0.2.3 <0.3.0   (zero-major: pins to minor)
^0.0.3  →  >=0.0.3 <0.0.4   (zero-zero: pins to exact patch)

的包表示“不稳定 API”——任何次要版本都可能破坏功能。caret 尊重这一信号,变得更为保守。 0.x.x tilde ~ —— 仅补丁级别更新

tilde 更加保守。它接受新的补丁版本,但不会触及次要版本:

当你希望获取补丁修复,但又不确定该库对次要版本的语义化版本控制是否遵守,或者你的代码与特定 API 表面紧密耦合,而新功能发布通常伴随细微行为变化时,就应使用

~1.2.3  →  >=1.2.3 <1.3.0   (any 1.2.x at or above 1.2.3)
~1.2    →  >=1.2.0 <1.3.0
~1      →  >=1.0.0 <2.0.0   (when only major given — same as ^1)

reach for ~

比较操作符:>=, <=, >

你可以使用比较操作符编写任意范围。两个约束之间用空格分隔表示“AND”:

>=1.2.0           # at least 1.2.0, no upper bound
>=1.2.0 <2.0.0   # same as ^1.2.0 (explicit AND)
>1.2.0 <=1.5.0   # between these values, exclusive/inclusive

这些在 peerDependencies中最为常见,其中某个库会声明其兼容的主机版本。 "react": ">=16.8.0 <19.0.0" 通配符:* 和 x

通配符形式主要用于文档可读性;npm 将其视为零基础的 caret/tilde 操作符:

——任意版本。不要在生产环境中使用。

  • *"" ——任意 1.x.x(等同于
  • 1.x1.x.x ——任意 1.2.x(等同于 ^1.0.0)
  • 1.2.x 预发布版本 ~1.2.0)

预发布版本看起来像

。它们被视为 1.0.0-alpha.1, 2.0.0-beta.3, 或者 3.1.0-rc.1低于 具有相同数字的正式版本—— 关键的是, 1.0.0-alpha.1 < 1.0.0.

范围操作符不会自动包含预发布版本 。一个范围不会拉入 ^1.0.0 ,即使它在技术上满足 1.1.0-beta.1。你需要明确选择: >=1.0.0 <2.0.0这是有意的安全措施。你很少希望 CI 会默默地拉取一个依赖项的预发布构建,因为其恰好满足版本范围。如果你在测试预发布版本,应主动进行。

npm install some-library@next
npm install some-library@2.0.0-beta.3

锁定文件不是可选的 -alpha 当 npm 解析你的

范围时,它会选择当前可用的最高兼容版本

在那一刻 ^1.2.3 今天你得到 。六个月后再次运行,你可能会得到。运行 npm install 。相同的 1.5.0,不同的依赖树,潜在的行为差异。 1.9.2这就是锁定文件解决的问题。 package.json(npm) 和

(yarn) 记录每个依赖项(直接和间接)的确切版本。当其他人克隆你的仓库并运行 package-lock.json 时,他们将获得完全相同的依赖树。 yarn.lock 将锁定文件提交到代码库。始终如此。 npm ci不提交锁定文件意味着:

不同开发者可能运行不同的依赖版本而不知情 你的 CI 环境可能悄然偏离你的本地环境

  • 一个间接依赖项的更新可能会改变生产行为,而你的
  • 没有任何明显变化
  • 主要例外:已发布的库(而非应用程序)通常不将锁定文件提交到源代码控制,以便消费者可以自行解析其依赖树。如果你在开发一个应用程序,就没有理由将锁定文件排除在源代码控制之外。 git diff

package.json 中的 "latest" 始终是一个错误

偶尔你会在

中看到这种写法 package.json:

"dependencies": {
  "some-package": "latest"
}

不要这样做。 "latest" 映射到 npm 上当前标记的版本——每当维护者发布新版本时,它都会改变。在一台新机器上运行的 latest 可能会拉取一个与你测试时完全不同的主要版本。 npm install 它可能在几周内运行良好,然后在包发布新主要版本时突然中断。更糟糕的是,它使

成为一个不可复现的规范——你无法在不手动检查 npm 的情况下了解你正在运行的版本。请锁定到一个真实版本,并让 caret 处理该范围内的安全更新。 package.json 检查某个版本是否满足一个范围

如果你不确定某个版本是否满足给定范围——特别是针对零主要版本包或不寻常的复合表达式——使用

在 iotools.cloud 上可以立即得到答案。输入范围( SemVer 版本计算器及范围测试器 )和候选版本,它会告诉你该约束是否满足。^1.2.3, ~0.5.0, >=2.0.0 <3.0.0这在审查依赖项升级的 PR、调试为何

解析到意外版本,或在发布库前检查一个 npm install 范围时非常有用。 peerDependencies 操作符

快速参考

解析为例子1.2.0 或更高,无上限
^^1.2.3>=1.2.3 <2.0.0
~~1.2.3>=1.2.3 <1.3.0
>=>=1.2.0任意版本(避免使用)
**任意 1.2.x 补丁
x1.2.x精确匹配
正好是 1.2.31.2.3语义化版本控制:package.json 中数字的实际含义 2
想要享受无广告的体验吗? 立即无广告

安装我们的扩展

将 IO 工具添加到您最喜欢的浏览器,以便即时访问和更快地搜索

添加 Chrome 扩展程序 添加 边缘延伸 添加 Firefox 扩展 添加 Opera 扩展

记分板已到达!

记分板 是一种有趣的跟踪您游戏的方式,所有数据都存储在您的浏览器中。更多功能即将推出!

广告 移除?
广告 移除?
广告 移除?

新闻角 包含技术亮点

参与其中

帮助我们继续提供有价值的免费工具

给我买杯咖啡
广告 移除?