最近遇到一个yarn的bug,搜索之后发现它竟然存在6年之久,这到底是个怎样神奇的问题?经过一番分析排查,我给了6个解决方案。。。
1、问题描述
最近接手的几个项目包管理器用的是 yarn@v1.22.19
,在安装依赖后无论是否成功,总是出现网络连接问题而且会卡很长时间,然后会出现几行这样的异常日志:info There appears to be trouble with your network connection. Retrying...
。
有时一些神奇的包(比如 node-sass
)出现异常会导致安装失败,结果卡了半天才发现失败,真的让人很崩溃。另外在yarn
的 github
仓库中有数十条相关的 issue
,时间跨度从2016年到2022年足足6年,原因和方案众说纷纭。我很好奇这到底是个什么神奇的问题居然6年都没解决,因此决定一探究竟。【相关教程推荐:nodejs视频教程 、编程视频】
2、问题排查
2.1、关键词搜索
2.1.1、搜索 github
碰到没啥思路的问题和报错,第一技巧是搜它。在yarn
的 github
仓库中搜索报错信息 There appears to be trouble with your network connection
,可以看到结果中有1个相关代码和91个相关 issue
。在 issue
里找了一会没找到合适的方案,接着进入下一步:搜索代码。
2.1.2、搜索代码
由于网络原因这里直接转到本地 yarn
的安装目录进行查找。用 vscode
打开 yarn
的安装目录(我的本地目录是~/.volta/tools/image/yarn/1.22.19
),全局搜索关键词 There appears to be trouble with your network connection
。可以看到结果同样只有1个,整串错误信息赋值给了一个变量offlineRetrying
。
全局搜索关键词offlineRetrying
共2处结果,除去上一步的结果只有1处引用。这里的代码主要是抛出异常和重试,没有更多关键词可以挖掘。接下来进入调试环节,在 offlineRetrying
这行代码前面打个断点,调试看看具体错误信息和上下文。
2.2、程序调试
2.2.1、确定调试命令
安装依赖需要运行命令 yarn
, 那要怎么调试它呢?yarn
是一个 npm
包,执行时实际是调用 node xxx.js
,而这个 xxx.js
一般配置在 package.json
的 bin 字段中。从下图可以看到 yarn
对应的文件是 ./bin/yarn.js
,所以可以使用这行调试命令:node --inspect-brk ~/.volta/tools/image/yarn/1.22.19/bin/yarn.js
。(关于 Node.js
的调试可以参考官方文档)
2.2.2、开始调试
先在变量 offlineRetrying
所在的代码行cli.js:66099
之前添加 debugger 语句。
然后回到业务项目的根目录中,运行调试命令 node --inspect-brk ~/.volta/tools/image/yarn/1.22.19/bin/yarn.js
。此时程序挂起等待调试工具连接,并打印出以下日志:
接着打开 chrome
内置的调试页面 chrome://inspect/#devices
,找到文件路径相同的 Target
,点击 inspect
按钮开始调试。
接着 chrome
会打开一个独立的 DevTools
窗口,由于使用的是 node --inspect-brk
命令,此时 DevTools
自动断点在被调试文件的起始位置,需要按下 F8
跳过该断点继续执行。
等待一小段时间后,DevTools
停在之前添加的断点处,可以看到这是一个超时异常,导致异常的请求是GET: https://yarnpkg.com/latest-version
。使用 curl
请求这个链接,结果是 210s 超时。使用代理访问这个链接可以成功,但是请求被重定向到 classic.yarnpkg.com/latest-vers…,其返回结果是 1.22.19
。
至此问题基本清楚了,主要是请求超时并且多次重试导致了文章开头的问题,可以使用代理规避这个问题。如果排查到此结束就没意思了。
2.2.3、深入排查
为了进一步了解 yarn
为什么要请求 yarnpkg.com/latest-vers…,以该链接为关键词在代码中搜索,找到了这个关键词链条:https://yarnpkg.com/latest-version
-> SELF_UPDATE_VERSION_URL
-> _checkUpdate
-> checkUpdate
,实际调用关系则正好相反,具体如下图:
3、确定原因
前面已经推断出超时链接的调用关系是: checkUpdate
-> _checkUpdate
-> SELF_UPDATE_VERSION_URL
-> https://yarnpkg.com/latest-version
,再结合 checkUpdate
函数的注释和代码来看,每次执行 yarn
安装命令的时候都会请求 yarnpkg.com/latest-vers…,从而检查是否有新版本需要更新。但是这个链接访问超时而且失败后会重试,默认的超时时间为 30s 重试次数为 4 次,所以安装完成后还会卡 120s 程序才会真正结束。
4、解决方案
引发问题的关键因素有3个:检查更新、超时、重试,因此可以从优化网络、调整超时时间、跳过检查更新3个方向去解决问题,以下有6个解决方案可以参考。
4.1、优化网络
这个思路很容易想到,既然访问超时,那就提升请求速度。
- 【方案1】使用代理优化网络(推荐)
$ yarn install --proxy "http://{domain}:{port}" --https-proxy "http://{domain}:{port}"
以我的开发环境举例,命令长这样:
yarn install --proxy "http://10.180.55.191:7890" --https-proxy "http://10.180.55.191:7890"
4.2、调整超时时间
这个思路比较直接,适用场景更多些,如果其他方法不奏效可以试试。
- 【方案2】修改 network-timeout(看情况)
默认超时时间为 30s 可以改小为 2s,修改后异常依然存在,但是可以让检查更新快速失败不用等几分钟。
yarn install --network-timeout 2000
有一部分开发者表示出现异常是因为某些大型
npm
包安装太久超过了默认超时时间 30s,因此也可以把network-timeout 改得更大避免异常。
4.3、跳过检查更新
这个思路的解决方案主要来自 checkUpdate
函数中的几个终止条件。
- 【方案3】修改配置禁止检查更新(推荐)
$ yarn config set disable-self-update-check true$ yarn install
- 【方案4】修改配置把上次更新时间调到百年后(推荐)
$ yarn config set lastUpdateCheck 1e13 $ yarn install
- 【方案5】执行命令时禁用交互式提示(推荐)
$ yarn install --non-interactive
- 【方案6】修改代码跳过检查更新(不推荐)
- 找到
yarn
的安装目录注释checkUpdate
的调用,具体代码行为cli.js:7261
,修改后长这样:// this.checkUpdate();
- 也可以修改其他可以阻断
checkUpdate
函数的代码...
- 找到
5、最后
以上主要是分享一些问题分析排查的经验,另外也提供了一些 yarn install
超时异常的解决方案,希望能对前端同学们有所帮助。
在快写完这篇文章的时候,yarnpkg.com/latest-vers… 已经可以正常访问,不知道还会不会有人再遇到这个问题。
另外我在
yarn
的github issue
中回复了以上的解决方案,希望前端同学们少受点折磨,也希望官方早点修复这个6年陈的老Bug。?
更多编程相关知识,请访问:编程教学!!
以上是记录并分析分析一个yarn存在6年之久的bug的详细内容。更多信息请关注PHP中文网其他相关文章!

JavaScript核心数据类型在浏览器和Node.js中一致,但处理方式和额外类型有所不同。1)全局对象在浏览器中为window,在Node.js中为global。2)Node.js独有Buffer对象,用于处理二进制数据。3)性能和时间处理在两者间也有差异,需根据环境调整代码。

JavaScriptusestwotypesofcomments:single-line(//)andmulti-line(//).1)Use//forquicknotesorsingle-lineexplanations.2)Use//forlongerexplanationsorcommentingoutblocksofcode.Commentsshouldexplainthe'why',notthe'what',andbeplacedabovetherelevantcodeforclari

Python和JavaScript的主要区别在于类型系统和应用场景。1.Python使用动态类型,适合科学计算和数据分析。2.JavaScript采用弱类型,广泛用于前端和全栈开发。两者在异步编程和性能优化上各有优势,选择时应根据项目需求决定。

选择Python还是JavaScript取决于项目类型:1)数据科学和自动化任务选择Python;2)前端和全栈开发选择JavaScript。Python因其在数据处理和自动化方面的强大库而备受青睐,而JavaScript则因其在网页交互和全栈开发中的优势而不可或缺。

Python和JavaScript各有优势,选择取决于项目需求和个人偏好。1.Python易学,语法简洁,适用于数据科学和后端开发,但执行速度较慢。2.JavaScript在前端开发中无处不在,异步编程能力强,Node.js使其适用于全栈开发,但语法可能复杂且易出错。

javascriptisnotbuiltoncorc; saninterpretedlanguagethatrunsonenginesoftenwritteninc.1)javascriptwasdesignedAsalightweight,解释edganguageforwebbrowsers.2)Enginesevolvedfromsimpleterterterpretpreterterterpretertestojitcompilerers,典型地提示。

JavaScript可用于前端和后端开发。前端通过DOM操作增强用户体验,后端通过Node.js处理服务器任务。1.前端示例:改变网页文本内容。2.后端示例:创建Node.js服务器。

选择Python还是JavaScript应基于职业发展、学习曲线和生态系统:1)职业发展:Python适合数据科学和后端开发,JavaScript适合前端和全栈开发。2)学习曲线:Python语法简洁,适合初学者;JavaScript语法灵活。3)生态系统:Python有丰富的科学计算库,JavaScript有强大的前端框架。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器

螳螂BT
Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

适用于 Eclipse 的 SAP NetWeaver 服务器适配器
将Eclipse与SAP NetWeaver应用服务器集成。

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。