npm、pnpm、yarn 安装依赖超时,先看报错类型再动参数
前端项目安装依赖卡在某一个包、反复重试后报 ETIMEDOUT 或 ECONNRESET,是很多开发者在新环境、CI 或者跨境网络下都会碰到的问题。常见反应是直接换一个 registry,但换源只解决「地址远」,解决不了「连接中途被断」或者「并发太高被限流」。本文对照 npm、yarn 官方文档里的配置项,加上 pnpm 的同类设置,说明三个包管理器各自能调哪些参数,以及怎么根据报错判断该调哪一个。参数名称与默认值会随版本变化,下文数值以文档查阅时为准,请在你本机用对应命令再核对一次。
先判断:超时、断连、解析失败不是一回事
同样是「装不上」,背后的原因至少有三类,处理方法不同。
ETIMEDOUT 和 ESOCKETTIMEDOUT 说明什么
这类报错表示连接建立或者数据传输等待超过了限定时间。可能是线路延迟高、某个包体积大下载慢,也可能是超时参数本身设得偏小。这一类适合调大超时和重试次数。
ECONNRESET 又是什么原因
连接被对端或者中间设备重置,常见于并发请求太多、链路中途丢包、或者中间代理对长连接不友好。这一类适合先降低并发,再看是否需要重试。
EAI_AGAIN、ENOTFOUND 为什么先查解析
这两个代码指向域名解析阶段,与下载速度无关,调超时参数通常无效,应当回到解析与代理设置上排查,可以对照本机、容器、隧道三处解析不一致的排查。
npm:重试、超时、并发各是哪几个配置
根据 npm 官方配置文档,和网络直接相关的几个选项及默认值如下:
| 配置项 | 默认值 | 作用 |
|---|---|---|
| registry | https://registry.npmjs.org/ | 包仓库的基础地址 |
| fetch-retries | 2 | 拉取包失败后的重试次数 |
| fetch-retry-mintimeout | 10000 毫秒 | 重试等待的下限 |
| fetch-retry-maxtimeout | 60000 毫秒 | 重试等待的上限 |
| fetch-timeout | 300000 毫秒 | 单个 HTTP 请求允许的最长等待 |
| maxsockets | 15 | 对同一个源的最大连接数 |
也就是说,npm 默认其实已经给了 5 分钟的请求超时,如果你的报错出现得很快,多半不是 fetch-timeout 太小,而是连接被重置或者解析失败。针对 ECONNRESET,更值得动的是 maxsockets 与重试次数:
npm config set fetch-retries 5
npm config set fetch-retry-maxtimeout 120000
npm config set maxsockets 5
npm config get registry
上面的数值只是起点,而不是推荐值,建议每次只改一项,改完用 npm install --loglevel verbose 观察失败出现的位置。如果项目里已有 lockfile,要注意 lockfile 里记录了每个包的下载地址,切换 registry 后要看一下依赖变更是否被写入 diff,再决定要不要提交。
pnpm 与 yarn:参数名不同,思路一致
pnpm 的并发为什么要单独看
pnpm 在安装时会并行下载大量包,网络不稳时反而容易触发连接重置。它的设置里有 networkConcurrency(旧写法为 network-concurrency)控制并发请求数,并且同样提供 fetchRetries、fetchRetryFactor、fetchRetryMintimeout、fetchRetryMaxtimeout、fetchTimeout 这一组重试与超时设置。新版本文档把这些非敏感设置放在 pnpm-workspace.yaml,早期版本则写在 .npmrc 中,具体默认值请以你使用版本的官方设置页面为准。
yarn 经典版与 Berry 版写法为什么不同
Yarn 经典版(1.x)使用命令行参数 --network-timeout,也可以写进 .yarnrc,单位是毫秒;Yarn Berry 使用 .yarnrc.yml,对应配置是 httpTimeout、httpRetry 和 networkConcurrency。按 Berry 官方配置文档,httpTimeout 默认 1 分钟,httpRetry 默认 3,networkConcurrency 默认 50,文档特别提到在严格限制的代理后面可能需要把并发降下来。
# Yarn Berry 的 .yarnrc.yml
httpTimeout: 120000
httpRetry: 5
networkConcurrency: 16
示例里的数字是调试起点,请结合你的网络状况逐步调整,不是通用标准值。
一套可以复现的调参步骤
- 用
npm config get registry或对应工具的配置命令,确认当前实际使用的源,避免项目级和用户级配置互相覆盖。 - 清理失败时的现场:删除半途的
node_modules,保留缓存,再装一次,看是否在同一个包上失败。 - 如果每次都在同一个包上失败,用
curl -I直接请求这个包的下载地址,对比耗时,判断是单个地址不稳还是整体不稳。 - 失败位置随机时,先把并发降到较低值,再逐步提高,找到稳定的临界点。
- 在不同时段和不同网络下各装三次,记录耗时和失败次数,用数据判断而不是凭一次结果。
CI 环境还要额外留意:流水线通常每次都是干净环境,缓存命中率低,超时和重试更重要,可以参考CI 拉依赖超时时先看这些。想对比 pip、cargo 等其他语言的做法,可以看多语言依赖超时的镜像与参数配置。
参数调完仍不稳定时,问题可能在出口线路
如果降低并发、增加重试后仍然在固定时段频繁失败,说明瓶颈更可能在开发机到仓库之间的线路,而不是包管理器本身。这时可以先用 curl -w 记录连接耗时做对比。需要长期稳定的出口时,NasaCode 提供面向开发场景的线路与 AI 智能路由,适合把 npm、git、容器仓库这类请求放在同一条稳定链路上;效果以你按上面步骤做的前后对照为准,不必只看单次安装速度。
小结
依赖安装超时,先分清是超时、连接重置还是解析失败,再选择调超时、降并发还是回头查 DNS。npm 重点是 fetch-retries 和 maxsockets,pnpm 看 networkConcurrency 一组,yarn 经典版看 --network-timeout,Berry 版看 httpTimeout 与 networkConcurrency。所有数值都需要在你的环境里做对照,再决定是否写进团队的统一配置。









