为啥我安装的依赖版本号一直不对,原来是它在搞鬼。

一、始终不正确的依赖版本号

在晨会上,组员们逐一分享了昨日的工作进展。期间,一位组员分享了他遇到的一个困难:"昨天,当我尝试安装A部门提供的一个组件库时,发现其中一个依赖的版本号始终不正确,导致组件库报错无法使用,我向A部门咨询,但他们一直坚持说组件库的依赖版本号设置是没有问题的。那个依赖他们所要求的版本是3.5.1-alpha.5,而我安装后版本都是3.5.1。"

"等会儿我帮你看看。很可能是依赖版本号前面的符号引起的问题。"

二、检查组件库的package.json文件

项目使用pnpm作为包管理工具,因此需要在node_modules文件夹下的.pnpm目录中查找该组件库包的代码。

在找到的package.json文件中,我注意到dependencies字段里的依赖版本号前都加了^符号。

到这里,我心里就有谱了,应该是^符号搞得鬼。

三、^符号的作用

在这之前先介绍一下依赖版本号的组成,在语义版本控制中,依赖版本号通常由主版本号、次版本号、修订号三个主要部分组成,这三部分通过点号(.)分隔,例如:3.5.1。还可以通过在版本号后添加连字符(-)和一个标识符(alphabetaRC)来指定预发布版本,如 3.5.1-alpha.5。还可以通过在版本号后添加加号(+)和一些元数据来指定,如 3.5.1+build.456

^ 符号在 package.json 文件中用于指定依赖包版本范围,允许自动更新到当前主版本号中的最新稳定版本,但不会更新到下一个主版本号以避免破坏性更改

四、搞笑的版本发布

那个无论怎么安装但是版本号都不对的依赖,在组件库中的版本被指定为 ^3.5.1-alpha.5。这意味着当我们使用 pnpm 包管理器安装此依赖时,它会选择安装主版本号为 3 的最新稳定版本,即 3.5.1,尽管 3.5.1-alpha.5 的发布时间晚于 3.5.1

这里的关键在于,3.5.1-alpha.5 被视为预发布版本,包管理器将其认定为不稳定的。即便它是按时间顺序的最新版本,包管理器仍会优先选择安装稳定版本 3.5.1,以避免潜在的破坏性更改。

因此,即使后续再发布的或之前已经发布的其他预发布版本,使用 ^ 符号的安装命令依然会默认安装 3.5.1 版本。

这意味着,尽管 A 部门出于修复 3.5.1 版本中的错误而发布了 3.5.1-alpha.5,并且在组件库中使用 ^ 符号指定版本号,但这实际上并未达到预期目的,因为安装时仍会回退到 3.5.1 的稳定版本。

更严重的是,如果生产环境的组件库中指定的依赖版本为 ^3.5.1-alpha.4,那么尽管 3.5.1-alpha.4 版本本身不会引起组件库报错,但如果重新部署生产环境,这个依赖将会被更新到 3.5.1 版本,这是一个已知会导致组件库报错的版本,从而可能触发一次生产事故。

五、如何自救

如果跟 A 部门说明情况后,A 部门仍然坚持说组件库的依赖版本号设置是没有问题的,我们该如何自救呢?

可以使用 resolutions,此字段允许您指示 pnpm 覆盖依赖关系图中的任何依赖项,可以利用来锁定依赖版本,来完成自救。

package.json文件中添加如下配置:

json 复制代码
"resolutions": {
  "xxx": "3.5.1-alpha.5"
}
相关推荐
时空无限17 小时前
EFK 中使用 ruby 和 javascript 脚本去掉日志中颜色字符详解
linux·javascript·elk·ruby
万少20 小时前
HarmonyOS官方模板集成创新活动-流蓝卡片
前端·harmonyos
-To be number.wan1 天前
C++ 赋值运算符重载:深拷贝 vs 浅拷贝的生死线!
前端·c++
噢,我明白了1 天前
JavaScript 中处理时间格式的核心方式
前端·javascript
纸上的彩虹1 天前
半年一百个页面,重构系统也重构了我对前端工作的理解
前端·程序员·架构
be or not to be1 天前
深入理解 CSS 浮动布局(float)
前端·css
LYFlied1 天前
【每日算法】LeetCode 1143. 最长公共子序列
前端·算法·leetcode·职场和发展·动态规划
老华带你飞1 天前
农产品销售管理|基于java + vue农产品销售管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
小徐_23331 天前
2025 前端开源三年,npm 发包卡我半天
前端·npm·github
C_心欲无痕1 天前
vue3 - 类与样式的绑定
javascript·vue.js·vue3