线上BUG引起思考:package.json 中的 ^~ 该保留吗?

news2024/12/27 11:22:43

一、写在前面
一次线上项目 bug,引发了关于 package.json 中的 ^~ 是否该保留?保留可能引发的后果?以及如何在版本更新便利和版本更稳定中取舍的思考?这个 bug 是由于线上部署打包时,自己下载了最新依赖,于是线上依赖版本和研发本地依赖版本不同,不巧的是最新依赖有 bug 而本地早先下载的没有, 导致了定位 bug 浪费了大量时间。

最后是发现 lock 的版本有差异,根据这个方向进一步定位到了 bug。

而会导致这种版安装的依赖版本差异的决定性原因则是 package.json 没有写死版本号,而是使用允许根据市场版本更新的指令符号 ^~。

那么如果希望避免上诉 bug,锁定依赖版本,可行的方案是什么?

本文将以上诉 bug 为引,尝试简单讨论和认识:

①package.json 中的 ^ ~
②依赖版本锁定:yarn 和 npm 等的 lock 锁定
③依赖版本锁定:package.json 的锁定
④让Git记下 lock 的变更记录的意义
⑤小结:前端工程项目依赖版本锁定的小结
二、package.json 中的 ^ ~
在这里插入图片描述

  1. ^ 意思是要更新【次版本】,当市场有更新的版本时,例如:package.json 中是"^2.1.0",库可能会更新到2.2.0的最新版本,但不会更新到3.0.0版本。 ~
  2. 意思是要更新【补丁版本】,当市场有更新的版本时,例如:package.json 中是"~2.1.0",库可能会更新到2.1.1的最新版本,但不会更新到2.2.0版本。
  3. 版本号前面啥也没有,表示写死了版本号,无论何时何地安装的依赖版本只会是这个。

三、怎么锁定工程依赖的版本
在实践中,工程依赖的版本锁定,可能会有两方面的考虑,一是通过包管理工具的 lock 进行版本依赖锁定, 二则是通过在 package.json 中写死版本号来“绝对锁定”依赖版本。依赖版本的锁定,是必须要考虑, 否则一个差异和不幸可能需要浪费大量时间去定位由此导致的 bug,那将是痛苦而不值得的,尽管发生的机会比较小。

3.1 package.json 的锁定
毫无疑问,package.json 具有依赖版本的决定权。是否在安装依赖时,下载新版本,是否修改 lock 版本,是由 package.json 中附带 ~ ^等命令符号结合市场最新版本决定的, 在决定性因素上,与使用的包管理工具并无多大关系,无论是 npm、yarn 或 pnpm。

只要,package.json 写死版本号,版本号前不携带那些 ~ ^等符号,那么无论何时何地何人安装依赖,依赖版本都会是一致的。

因此,在功能已经开发完毕,进入运维阶段的前端工程项目,如果希望减少由于依赖版本差异带来的莫名其面的 bug,那么写死 package.json 中版本号是可行可靠的。如果确有需要升级依赖版本,再单独手动去升级。项目上线转运维阶段后,需要批量更新依赖,从而使用新依赖的新功能的可能性较小, 而运维中项目保证项目的稳定才是更重要工作,毕竟“还能跑就行”。

3.2 yarn 和 npm 等的 lock 锁定
矛盾是总是存在的,总有不希望一个一个手动更新依赖的需求,总有希望“一键更新全部依赖”的场景。这种时候,package.json 中写死版本号,则不是期望的。那么某种程度上的依赖本锁定则出现了,这就是通过包管理工具的 lock 来锁定,例如 yarn 的 yarn.lock,npm 的 package-lock.json, 以及 pnpm 的 pnpm-lock.yaml。

据我观测一些知名的开源项目,通常也不会全部一锤将版本号都写死中 package.json,并且通常让Git记下 lock 的变更记录。例如:
在这里插入图片描述
在这里插入图片描述
3.3 yarn.lock 和 package-lock.json 下载新依赖上的区别
包管理工具的 lock 也具有某种程度上的“依赖版本锁定”功能,尽管不同的工具的 lock 表现具有差异。例如当 package-lock.json 存在时,即使市场上有比 package-lock.json 中锁定版本更新,且 package-lock.json 中存在 ^ ~ 允许更新, 安装的版本也只会是 package-lock.json 中锁定的版本,不会自动下载更新的版本。当然当 package.json 中版本被手动更新,会触发的 package-lock.json 连带变更。

而 yarn 的 yarn.lock 的“版本锁定”的则表现不同,当市场有比 yarn.lock 中更新的版本,且 package-lock.json 中存在 ^ ~ 允许更新, 那么 yarn 会自动安装比 yarn.lock 更新的版本并且主动修改 yarn.lock。

从这个差异角度看,package-lock.json 的“版本锁定”更可靠,可以起到依赖版本保持一致的作用,而 yarn.lock 则不具备。

3.4 让Git记下 lock 的变更记录
既然 yarn.lock 无法帮助我们“锁定”版本,那么 yarn.lock 的意思而在?我并不清楚 yarn.lock 设计全部意义,但我可以确定的一个价值是: 让Git记下 lock 的变更记录,有助于追踪使用的依赖版本记录,有时会很有作用,例如定位某类bug时。

即使 lock 会被修改,它的存在也会很有价值,例如:证明此前被 lock 的版本在本工程是可用的。因为会存在某个新下的最新版本存在缺陷或不符合本工程的需求的情形。这个新版本缺陷可能会导致工程无法运行或运行异常。

一个例子是,新同事安装工程出现工程运行异常,而旧同事正常,且通过 git 证明业务代码无差异,package.json 也无差异,此时差异会体现在 lock 的版本。此时要想使用最新且能确保本工程正常运行的依赖版本,那么旧同事 lock 的依赖版本就是答案。

而 package.json 中的版本虽然可用,但由于具有时间跨度的不确定性,可能会比 lock 的要旧很多。

知名的例子是 vue-router 的 issues #2881 中提到的,在升级了 Vue-Router 版本到3.1.0及以上之后,页面在跳转路由控制台会报Uncaught (in promise)的问题,从而导致某些场景的跳转异常。

3.5 关于依赖地狱( Dependency Hell)和依赖分身(Doppelgangers)
package.json 的依赖版本设置作用仅有效于当前工程,实践中依赖锁定往往会涉及嵌套依赖等问题,因为依赖也可能会有 package.json,依赖的依赖也可能会有 package.json。

但本文暂不讨论,关于依赖地域( Dependency Hell)和依赖分身(Doppelgangers)的问题。

四、小结

总结上述简单的分析和讨论,小结如下:

①package.json 具有锁定依赖版本的决定权,包管理工具不具有。 ②package.json ^ 意思是要更新【次版本】,~
意思是要更新【补丁版本】。 ③yarn 的 yarn.lock 和 npm 的 package-lock.json
对“锁定依赖版本”表现不同,package-lock.json 的“锁定效果”更可靠。 ④让Git记下 lock
的变更记录是有意义的。一些知名开源项目都让Git记下 lock 的变更记录。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1320044.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何本地搭建Zblog网站并通过内网穿透将个人博客发布到公网

文章目录 1. 前言2. Z-blog网站搭建2.1 XAMPP环境设置2.2 Z-blog安装2.3 Z-blog网页测试2.4 Cpolar安装和注册 3. 本地网页发布3.1. Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 正文开始前给大家推荐个网站,前些天发现了一个巨牛的 人工智能学习网站…

12.DHCP

DHCP 用户上网的时候,会从网卡发一个DHCP请求,是一个广播报文255.255.255.255,源地址是0.0.0.0 服务器得到请求后,返回给客户端一个地址 1.在路由器开启DHCP功能 2.配置地址池 3.指明给用户分配的网段…

制造企业MES管理系统可以和AI结合应用吗

在当今的数字化时代,人工智能AI和MES生产管理系统的结合将成为制造企业发展的重要趋势。这种结合可以为制造企业带来许多优势,如提高生产效率、降低成本、优化资源利用等。本文将探讨MES管理系统和AI的结合以及它们在制造企业中的应用,并分析…

Gateway网关-路由的过滤器配置

目录 一、路由过滤器 GatewayFilter 1.1 过滤器工厂GatewayFilterFactory 1.2 案例给所有进入userservice的请求添加一个请求头 Truthitcastis freaking awesome! 1.3 案例给所有请求添加一个请求头 Truthitcastis freaking awesome! 一、路由过滤器 …

鸿海携手Porotech共同开启Micro LED新篇章 | 百能云芯

近日,鸿海集团决定进一步强化其在Micro LED(微发光二极体)技术领域的实力。为此,鸿海宣布将与英国半导体企业Porotech展开战略合作,旨在共同开发MicroLED微显示器,并在AR(扩增实境)应…

Python学习之复习MySQL-Day8(事务)

目录 文章声明⭐⭐⭐让我们开始今天的学习吧!事务简介事务操作模拟转账操作开启事务提交事务回滚事务查看/设置事务提交方法实例演示 事务四大特性并发事务问题分类 事务隔离级别分类查看/设置事务隔离级别实例演示 文章声明⭐⭐⭐ 该文章为我(有编程语…

记录 | C++头文件中 <> 和 ““ 的区别

C 头文件中 <> 和 “” 的区别 #include <cstdio> #include "hello.h"int main(){printf("hello world!");return 0; }● <cstdio> 这种形式表示不要在当前目录下进行搜索&#xff0c;只在系统目录里搜索&#xff1b; ● "hello.h…

【网络安全】-Linux操作系统—操作系统发展历史与Linux

文章目录 操作系统发展历史初期的操作系统分时操作系统个人计算机操作系统 Linux的诞生UNIX与GNU项目Linux内核的创建 Linux的特点开放源代码多样性社区支持 Linux的应用服务器和超级计算机嵌入式系统桌面系统 总结 操作系统发展历史 操作系统&#xff08;Operating System&am…

Linux部署Nacos注册中心结合内网穿透实现远程访问UI管理界面

文章目录 1. Docker 运行Nacos2. 本地访问Nacos3. Linux安装Cpolar4. 配置Nacos UI界面公网地址5. 远程访问 Nacos UI界面6. 固定Nacos UI界面公网地址7. 固定地址访问Plik8. 结语 Nacos是阿里开放的一款中间件,也是一款服务注册中心&#xff0c;它主要提供三种功能&#xff1a…

电机驱动开发

最近在搞电机驱动程序&#xff0c;感觉很简单&#xff0c;实际操作却发现里面还有很多猫腻&#xff08;细节&#xff09;。 电机在嵌入式设备中非常常见&#xff0c;例如云台的转动&#xff0c;都是靠电机来驱动的。 电机常见分步进电机、直流电机&#xff0c;相对来说步进电机…

年度大盘点:AIGC、AGI、GhatGPT震撼登场!揭秘人工智能大模型的奥秘与必读书单

这里写目录标题 前言01 《ChatGPT 驱动软件开发》02 《ChatGPT原理与实战》03 《神经网络与深度学习》04 《AIGC重塑教育》05 《通用人工智能》 前言 在2023年&#xff0c;人工智能领域经历了一场前所未有的大爆发&#xff0c;特别是在语言模型领域。新的概念和英文缩写如AIGC、…

深度学习中的KL散度

1 KL散度概述 KL散度&#xff08;Kullback-Leibler Divergence&#xff09;&#xff0c;也称为相对熵&#xff0c;是信息论中的一个概念&#xff0c;用于衡量两个概率分布间的差异。它起源于统计学家Kullback和Leibler的工作&#xff0c;它的本质是衡量在用一个分布来近似另一…

轻松搭建FPGA开发环境:第三课——Vivado 库编译与设置说明

工欲善其事必先利其器&#xff0c;很多人想从事FPGA的开发&#xff0c;但是不知道如何下手。既要装这个软件&#xff0c;又要装那个软件&#xff0c;还要编译仿真库&#xff0c;网上的教程一大堆&#xff0c;不知道到底应该听谁的。所以很多人还没开始就被繁琐的开发环境搭建吓…

如何在Photoshop中调整图像大小

在Photoshop中调整图像大小是一项非常常见的技能。在这里&#xff0c;您将学习如何在Photoshop中调整图像大小 1. 打开你的图片 步骤 1 为了在Photoshop中调整图像大小&#xff0c;请打开它并转到顶部菜单栏。在那里&#xff0c;选择“文件”>“打开”。从硬盘驱动器中选择…

2024网工必备技术词汇大全(网络、运维、安全3大方向)

晚上好&#xff0c;我的网工朋友。 很多人学习一个新事物都是从整体到局部这个节奏进行的&#xff0c;如果你想学习网络&#xff0c;首先你要知道网络基础的整体框架是什么样的&#xff0c;老杨总之前整理了一张图&#xff0c;我偷偷放在这里。 有了框架&#xff0c;就需要细节…

单片机LCD1602

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、LCD1602是什么&#xff1f;二、LCD1602 原理三、显示一个字符四、如何显示四位数五、参考历程六、封装成一个显示 字符和一个显示任意四位数的函数总结 前言…

VUE3使用Echarts图表

前言&#xff1a; 基本可以按照Echarts官网的描述来使用&#xff0c;Echart官网 第一步&#xff1a; 安装 npm install echarts --save 第二步&#xff1a; 使用 //页面定义容器 <div class"content-box echarts-box"><!-- 图表 定义ref 方便获取通过 ref…

4.docker镜像及相关命令

目录 1 查看所有镜像 docker images 1.1 基本用法 1.2 docker images -q 只显示所有镜像ID 1.3 docker images -f [筛选条件] -q 只显示符合条件的所有镜像ID 1.4 docker images --no-trunc 显示完整的IMAGE ID 1.5 docker images --format [模板] 使用模板 2 从…

【算法提升—力扣每日一刷】五日总结【12/13--12/17】

文章目录 2023/12/13力扣每日一刷&#xff1a;[141. &#xff08;判断&#xff09;环形链表](https://leetcode.cn/problems/linked-list-cycle/)力扣今日两刷&#xff1a;[142. &#xff08;找入环点&#xff09;环形链表 II](https://leetcode.cn/problems/linked-list-cycle…

揭开`this`的神秘面纱:探索 JavaScript 中的上下文密钥(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…