ncu -u 拉取包超时的解决方法
场景
执行 ncu --deep -u 报如图所示错误,原因是获取包的版本超时

解决方法,加长超时时间
ncu --deep --timeout 50000 -u
--timeout 的单位是毫秒,作用于每一个包的版本查询请求,不是整个命令的总时长。默认值是 30000。
为什么会超时
npm-check-updates 的工作方式是逐个包去 registry 查最新版本。--deep 会把 monorepo 里所有子包的 package.json 都扫一遍,包数量成倍增长,请求量随之上去。国内直连 registry.npmjs.org 本来就不稳,几十上百个并发请求里出现几个慢查询是很常见的,任何一个超时整条命令就报错退出。
所以延长超时是「让慢请求有机会跑完」,治的是症状。真正的根因通常是网络路径,换源见效更快:
# 让 ncu 走镜像源查询版本
ncu --deep --registry https://registry.npmmirror.com -u
# 或者读取 npm 已配置的源(ncu 默认会读 .npmrc,但显式指定更可靠)
npm config set registry https://registry.npmmirror.com
需要注意镜像源有同步延迟(一般几分钟到十几分钟),刚发布的版本可能查不到。要精确查最新版就得回官方源,那时候再靠 --timeout 撑着。
并发数也是一个旋钮
--concurrency 控制同时发出的请求数,默认 8。网络差的时候降低它比延长超时更有效——请求少了,单个请求分到的带宽多了,反而更快完成:
ncu --deep --concurrency 2 --timeout 60000 -u
反过来在内网私服上跑可以调高,比如 --concurrency 20。
顺手记几个常用参数
# 只看不改(默认行为),加 -u 才会写 package.json
ncu
# 只升级指定包(支持通配和正则)
ncu -u -f "vite"
ncu -u -f "/^@vue\//"
# 排除某些包不升
ncu -u -x "typescript,eslint"
# 限制升级幅度:只升 patch / 只升 minor / 升到最新
ncu -u --target patch
ncu -u --target minor
ncu -u --target latest # 默认
# 交互式勾选(升大版本时应该用这个)
ncu -u -i
# monorepo:扫描所有 workspace 包
ncu -u --workspaces
ncu -u --deep # 递归找所有 package.json,比 --workspaces 更暴力
# 输出成 json 给脚本用
ncu --jsonUpgraded
--deep 和 --workspaces 的差别值得注意:--workspaces 读 package.json 里声明的 workspace 配置,只处理正式的工作区成员;--deep 是直接递归文件系统找所有 package.json(跳过 node_modules)。后者会把示例项目、fixture 目录之类的也算进去,这既是它请求量大容易超时的原因,也可能改到你不想改的文件。
--target 的实际取法
ncu -u 默认是 --target latest,会无视 package.json 里的 ^ / ~ 范围直接跳到最新版,包括跨大版本。这跟 pnpm up(遵循范围)完全不同,是很多人第一次用 ncu 就把项目搞崩的原因。
我现在的习惯是分两步走:
# 第一步:安全的补丁和小版本,可以放心一把梭
ncu -u --target minor && pnpm install && pnpm test
# 第二步:大版本挨个看,读 changelog 再决定
ncu -u -i --target latest
跑之前先 git commit,ncu -u 只改 package.json 不装包,改坏了 git checkout package.json 就能回滚。
现在其实可以不装 ncu
pnpm up -i --latest 和 npm outdated + npm update 已经覆盖了大部分场景,且 pnpm up -i 的交互界面比 ncu -i 好用(带 changelog 链接、按依赖类型分组)。我留着 ncu 主要是为了 --deep 这个能力——多包仓库里一次性看清所有子包的过期依赖,pnpm 目前没有完全等价的命令。
临时用一次不必全局安装:
pnpm dlx npm-check-updates --deep --timeout 50000 -u

还没有留言,来发表第一条吧~