触发条件

  • 服务器(腾讯云国内)上,bun/npm 安装依赖时走 mihomo 代理 127.0.0.1:7890(.npmrc 里 proxy/https-proxy)。
  • 依赖里包含 大包(>80MB),典型是 @anthropic-ai/claude-agent-sdk-linux-x64 和 -musl(各约 85MB 的原生二进制,属于可选依赖)。
  • 症状:bun install 长时间无进展(node_modules 数量不涨),最终报 Fail extracting tarball for ...;或卡在某个包的下载上。

根因

代理会截断大文件的传输:curl 走代理下 85MB 包只得到 ~729KB 不完整 tarball(gzip: unexpected end of file)。直连又慢(~150KB/s),也容易超时。bun 自己的下载器对截断处理不干净,反复重试直到超时。

解决步骤

  1. 优先跳过可选依赖(推荐,多数情况够用):

    bun install --frozen-lockfile --ignore-scripts --omit=optional

    --omit=optional 跳过可选依赖。很多原生二进制(koffi、SDK 二进制)都是可选的;运行时若用系统命令(如 CLAUDE_EXECUTABLE=/usr/local/bin/claude)就不需要它们。

  2. 若必须装某大包:用 curl 直连下载完整 tarball 并手动喂给 bun 缓存:

    # 1) 下载(直连,不用代理),用 gzip -t 校验完整性
    curl -sL -o /tmp/pkg.tgz "https://registry.npmjs.org/@scope/pkg/-/pkg-<ver>.tgz" --max-time 180
    gzip -t /tmp/pkg.tgz && echo OK
    # 2) 解压到 bun 缓存(去掉 package/ 前缀)
    mkdir -p ~/.bun/install/cache/pkg@<ver>@@@1
    tar -xzf /tmp/pkg.tgz -C ~/.bun/install/cache/pkg@<ver>@@@1 --strip-components=1
    # 3) 关键:在裸目录建版本软链,否则 bun 不认缓存仍会重新下载
    mkdir -p ~/.bun/install/cache/pkg
    ln -sf ~/.bun/install/cache/pkg@<ver>@@@1 ~/.bun/install/cache/pkg/<ver>@@@1

    之后重跑 bun install --frozen-lockfile --ignore-scripts。

下次如何识别

  • 安装卡住时先看 pgrep -af "bun install" 是否还活着、~/.bun/install/cache 最新目录的 mtime 是否还在涨。
  • 用 bun install --verbose 看它正在 GET 哪个 tarball(.tgz);如果 URL 指向 SDK 之类的大原生包,大概率就是截断问题。
  • 小包走代理正常、只有大包挂 → 锁定代理截断。

相关概念

  • npm 生命周期脚本 (Lifecycle Scripts)(--ignore-scripts 会跳过 install 脚本)
  • 服务器 mihomo 代理 127.0.0.1:7890 用于国内访问 npm/GitHub
  • 关联实践:kanna 升级部署(workspace/platform/docs/projects/kanna.md 里的依赖安装一节)

本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/nodejs