一次性搞懂 NPM 版本号规则

小麦2025年02月26日1754 字

前端朋友一定对包管理器 NPM 以及 package.json 不会陌生。

依赖管理可以说是前端开发过程中的家常便饭。

你是否还只会无脑 npm install --save?

版本号前面的那些符号有什么作用?

代码里写的版本和实际安装的版本一定相同吗?

语义化版本和依赖版本有什么区别?

带着这些疑问,咱们今天一次性搞懂。

另外在视频末尾,我会出给一些测验题目,大家可以试着在评论区里留下自己的答案。

package.json 依赖包的版本号有多种书写方式,比如 NPM 官方文档里给出的示例。

有带各种前缀符号的,有范围约束的,有一个英文单词的,有的甚至可以是一个 URL。

不同的写法会影响包管理器应该从哪里,以什么样的优先级,安装哪个具体版本。

有朋友可能知道一个叫做 Semantic Versioning(即语义化版本)的东西,

但需要注意的是,它并不等同于 package.json 中定义的依赖包版本。

我们首先有必要对这俩做一下区分。

语义化版本规范的原文我放这里了,它的内容看着多但并不复杂。

我让 DeepSeek 帮大家理解一下,

可以看到所有这些版本号都包含三个数字,以及一个可选的后缀。

语义化版本规范中约定了这几件事:

第一,将版本号分成三个部分,主版本、次版本和修订号。

第二,约定了各部分版本号的递增规则,

第三,不稳定版本号的定义。

第四,它们之间的大小关系,或者叫优先级规则。

而这些都是非强制性约定,这也就意味着开发者完全可以不遵守这些规则。

当然不遵守规则也会带来很多坏处,未来有机会我们再细说。

现在让我们回到依赖版本这里。

根据语义化版本规范,无论是 ^3.3.0,3.3.x 还是 next,都不是合法的语义化版本号。

实际上你在 dependencies 中书写的版本号,官方管它叫 "版本范围",并非版本号。

因此后面我们都统一叫版本范围。

OK,区分清楚语义化版本和版本范围的概念后,我们就可以讨论不同版本范围,对实际安装依赖包版本的影响。

首先从最常用的方式入手,当我们用 npm install --save 命令安装一个依赖包,那么它会自动获取当前依赖包最新(latest)的版本号并安装,然后在前面添加 ^ 号。

比如 some-package 这个包的最新版本号是 1.2.0,那么 npm 就会默认安装 ^1.2.0。

这里 ^ 号的含义,是 "锁定" 主版本号,即保持 x 不变,安装 y.z 中的最新版本 …. 吗?

让我来考考大家,假设 some-package 从 1.2.0 升级到了 1.2.1,重新安装会安装 1.2.0 还是 1.2.1 呢?

答案是显然是 1.2.1,这道题没有难度。

假设 some-package 又发了一个新版本 1.2.2-beta.1,那么重新安装会安装 1.2.2-beta.1 吗?

答案是不会。

这里我们需要理解什么是最新版本。

还记得我们之前在语义化版本规范中,提到的 “不稳定版本” 的约定吗?

NPM 会按照语义化版本的规范,将带有后缀的 1.2.2-beta.1 视为不稳定版本,除非依赖方强制指定该版本,否则永远也不会默认安装。

现在我们将代码改为 ^1.2.2-beta.1,这样就能安装这个 “不稳定” 版本了。

假设后续 some-package 又发布了一个新版本 1.2.2-beta.2,那么重新安装会安装 1.2.2-beta.2 这个版本吗?

答案显然是会。因为依赖方已经在代码里声明自己愿意接受不稳定版本了。

到这里你是否已经完全理解了呢?不,你还没有。我们再来看一个例子:

假设 another-package 的最新版本号是 0.2.0,之前你通过 npm install 安装的版本号是 "^0.1.0",那么重新安装时会安装 0.2.0 吗?

答案是不会,还是维持 0.1.0。

WTF,^ 锁的是主版本,0.2.0 明明就满足规则呀,这又是为什么呢?

按照语义化版本的规范,主版本号为 0 也表示它不 "稳定"。

因此,NPM 在安装依赖时,如果发现主版本号为 0,即便我们使用了 ^ 号,也会同时 "锁定" 次版本,等同于使用 ~ 号。

除非手动改成 ^0.2.0 或者 ~0.2.0,否则永远也不会安装最新的 0.2.0。

你看,区区一个版本范围的书写,就牵扯出这么多约定和规范,它不是一个简单的问题。

理解上面的通用规则之后就比较简单了,下面这张表展示了常见版本范围对应的安装规则,可以暂停看看,我就不念了。

像是 TAG(比如 latest、next 等)表示安装被开发者打上了这个标签的某个版本,可能是 1.2.0 也可能是 2.0.0。常用于体验新版本,需要完全信任开发者。

像是 URL(比如 https://,file:// 开头的)都表示从目标位置安装特定版本的包,常用于开发测试。

接下来我列一些测验,看看你是否已经掌握本期视频的核心要点。

左侧是 xmquiz 包的发布历史,请回答右边的每一种版本范围的实际安装版本。

这个包已经发布到 npmjs.com,你可以用这个命令实际测试看看和你思考的是否一致。

也可以把思考过程和答案贴在评论区,和大家交流。

本期我们区分了语义化版本和版本范围两个概念,学习了语义化版本规范的核心内容,以及各类版本范围的安装规则。

我是小麦,一位热爱分享的前端工程师,期待和你分享更多硬核有用的内容。

评论

你需要先登录才能发表评论
Made by 捣鼓键盘的小麦 / © 2025 Front Talk 版权所有