前端项目装依赖,代理没生效,十有八九是改错了文件。npm 和 pnpm 看 .npmrc;Yarn 1.x 通过 yarn config 写自己的 ~/.yarnrc;Yarn 2 及之后的 Berry 版本根本不读 .npmrc,只认 .yarnrc.yml 里的 httpProxy 和 httpsProxy。本文按 2026 年 11 月各工具的状态整理。
装依赖前先确认:你用的到底是哪一代 Yarn?
三个工具里最容易混的是 Yarn。运行 yarn --version,1.x 是经典版,2/3/4 都是 Berry。配置方式的差别如下,后面分别展开。
| 工具 | 配置文件 | 代理相关的键 |
|---|---|---|
| npm | ~/.npmrc 或项目里的 .npmrc | proxy、https-proxy、noproxy |
| pnpm | 同样的 .npmrc | https-proxy、http-proxy、proxy、noproxy |
| Yarn 1.x | ~/.yarnrc | proxy、https-proxy |
| Yarn 2+(Berry) | .yarnrc.yml | httpProxy、httpsProxy |
代理地址的写法(带认证、密码里有特殊字符要百分号编码等)和 给 git 配代理 里讲的完全一样,这里不重复。
npm 的代理怎么配?
两个键都设一遍最稳。registry 走的是 HTTPS,真正起作用的是 https-proxy,但只设 proxy 有时会让人误以为"已经配好了"。值是一个 HTTP 代理地址。
npm config set proxy http://proxy.example.com:8080
npm config set https-proxy http://proxy.example.com:8080
npm config set noproxy "localhost,127.0.0.1,.internal.example.com"
# 查看、测试、取消
npm config get https-proxy
npm ping
npm config delete proxy
npm config delete https-proxy
这些命令写入的是 ~/.npmrc。如果项目目录里也有 .npmrc,它的优先级更高,旧的错误配置常常藏在这里,用 npm config list 能看到每个值来自哪里。只想临时用一次,可以导出环境变量 HTTPS_PROXY / HTTP_PROXY,或者用 npm_config_https_proxy 这种"npm_config_ 加键名(横线换下划线)"的形式。
顺便区分一个常见混淆:registry 决定向哪台服务器要包(比如换成某个镜像源),代理决定走哪条路去连这台服务器。换镜像源不能代替代理,反过来也一样。
pnpm 的代理要不要另外配?
不用另起炉灶,pnpm 读同一批 .npmrc,上面 npm 的键直接适用。官方文档里列出的网络相关键是 https-proxy、http-proxy、proxy 和 noproxy,同样会回退到代理环境变量。
pnpm config set https-proxy http://proxy.example.com:8080
pnpm config set http-proxy http://proxy.example.com:8080
pnpm config get https-proxy
需要留意的是,较新的 pnpm 版本在把设置往 pnpm-workspace.yaml(驼峰命名)迁移。你的版本倾向哪种写法,以 pnpm.io 上对应版本的文档为准,别想当然。
Yarn 1 和 Yarn Berry 的写法有什么区别?
Yarn 1 的命令和 npm 几乎一样,Berry 则要改 YAML 文件,键名也换成驼峰。给 Yarn 3/4 项目往 .npmrc 里写代理是没用的。
# Yarn 1.x
yarn config set proxy http://proxy.example.com:8080
yarn config set https-proxy http://proxy.example.com:8080
# Yarn 2+:在项目或家目录的 .yarnrc.yml 里
httpProxy: "http://proxy.example.com:8080"
httpsProxy: "http://proxy.example.com:8080"
Berry 也可以用 yarn config set httpProxy 地址 来写,效果相同。
这些工具能直接用 SOCKS5 代理吗?
稳妥的结论是:文档里写的都是 HTTP(S) 代理地址,SOCKS 的支持随版本变化,不要默认可用。代理同时提供两种协议时,包管理器就指向 HTTP 端口。只有 SOCKS5 的话,可以在本机起一个 HTTP 转 SOCKS 的小转发程序,或者先查你所用版本的官方文档再决定要不要写 socks5://。
代理配了,install 还是失败,怎么看?
加详细日志重跑(比如 npm install --loglevel verbose),看第一个网络错误,而不是最后一个。常见情况对照:
- ETIMEDOUT / ECONNREFUSED 指向代理地址:主机、端口或协议写错,或者中间有防火墙。
- 407:认证没通过。检查密码是否被重置过、特殊字符是否编码。
- ECONNRESET:链路中途被断,先重试,必要时降低并发。
- SELF_SIGNED_CERT_IN_CHAIN 一类证书错误:通常是代理(或公司网关)在解密再签名 HTTPS 流量。用
cafile指向它的根证书,别随手把strict-ssl关掉。 - install 能过,postinstall 里下载二进制失败:很多包(如需要下载浏览器或原生二进制的)用自己的下载逻辑,读的是环境变量而不是
.npmrc,这时也要export HTTPS_PROXY=...。
在 CI 里还要多留意一点:.npmrc 一旦带着明文密码提交进仓库,就等于泄露。用环境变量注入,或者用不需要密码的白名单代理,更安全。
CI 和 Docker 构建里怎么传代理?
在持续集成里,最省心的办法是直接在作业环境里设置环境变量,不动任何配置文件:npm、pnpm 都会读,不少依赖的下载脚本也会读。变量名用大小写各一份最稳,再加上 NO_PROXY 把内网地址排除在外。
export HTTP_PROXY=http://proxy.example.com:8080
export HTTPS_PROXY=http://proxy.example.com:8080
export NO_PROXY=localhost,127.0.0.1,.internal.example.com
npm ci
构建镜像时同理,但别把代理写进 Dockerfile 的 ENV,否则它会留在最终镜像里。这部分放到后面的 Docker 代理文章里细讲。
怎么确认请求真的走了代理?
不要只看 install 成功与否,有些环境(比如本机恰好能直连)不走代理也能装上,配置错了反而发现不了。可以用下面三步确认:先 npm config get https-proxy 确认读到的值;再用 npm ping 做一次最小的 registry 往返,失败时它会直接打印网络错误;最后用 curl 通过同一个代理访问 registry,对比结果。
npm config get https-proxy
npm ping
curl -x http://proxy.example.com:8080 -I https://registry.npmjs.org/
curl 通、npm 不通,问题在 npm 的配置(文件优先级、键名、Yarn 版本);curl 也不通,问题在代理本身或网络路径。把问题缩到一边,排查就快多了。需要在 CI 里复现时,把这三条命令放在安装步骤前面,日志里能直接看到失败发生在哪一层。
安泊 VPN 能在哪里帮上忙
安泊 VPN 的代理 IP(HTTP/SOCKS5 proxy)独占一个 IP,HTTP 端口(含 HTTPS 隧道)和 SOCKS5 端口共用一组用户名密码;包管理器场景用 HTTP 这一种即可。可以设置来源 IP 白名单,命中的构建机无需密码,密码就不必写进共用的 .npmrc。重置密码后旧密码约 30 秒内失效,凡是写死了密码的配置文件都要同步更新。详见代理 IP 页面。


