npm publish 不走代理很慢:设置 npm proxy 解决
场景
使用了代理,npm 网站可以正常访问,但是 npm 发布包没有反应
具体表现是执行 npm publish 之后终端长时间没有任何输出,最后超时报错,或者卡在上传阶段不动。同一时间浏览器打开 npmjs.com 完全正常,这个反差容易让人误以为是包本身或者账号权限有问题,实际上是网络层没走通。
原因
npm publish 命令并没有走代理
这里的关键点是:代理软件开启后,浏览器能正常访问是因为浏览器读取了系统代理设置(或者装了代理插件),而命令行工具不吃这一套。绝大多数代理客户端默认只接管系统级的 HTTP/HTTPS 代理,命令行程序是否走代理,取决于它自己有没有读环境变量或者自己的配置项。
npm 的网络请求走的是 Node 的 http 模块,它不会自动读取系统代理。所以要么给 npm 显式配上代理,要么在 shell 里导出 http_proxy / https_proxy 环境变量。另外注意 npm install 之所以感觉不受影响,往常是因为把 registry 换成了国内镜像(比如淘宝源),走的是国内地址不需要代理;但发布必须打到官方 registry,这条路没有镜像可以代替,代理没配上就走不通。
顺带一提,如果 registry 当前指向的是镜像源,npm publish 也会失败或发到错误的地方,发布前可以先用 npm config get registry 确认一下是不是官方地址。
解决方法
设置 npm 代理
- 首先找到自己的代理服务器提供的代理信息,如下
https_proxy=http://127.0.0.1:7890
http_proxy=http://127.0.0.1:7890
all_proxy=socks5://127.0.0.1:7890
这三行一般能在代理客户端的界面上找到,端口号各家不同(Clash 默认 7890,V2Ray 常见 10809),照自己实际的填。这里要用的是 HTTP 代理那一条,不是 socks5 那条。
- 设置
git代理
npm config set proxy http://127.0.0.1:7890/
proxy 这一项管的是 HTTP 请求。npm 还有一项独立的 https-proxy 管 HTTPS 请求,而 npm registry 走的是 HTTPS,所以通常两项都要设上:
npm config set https-proxy http://127.0.0.1:7890/
注意 https-proxy 的值填的仍然是 http:// 开头的地址,因为这里描述的是「用哪个代理服务器」,而代理服务器本身监听的是 HTTP 协议,不是「用 https 连代理」。这一点经常写错。
配置写入的是用户级的 .npmrc 文件(~/.npmrc),是持久化的,重启终端后依然生效。也就是说代理软件关掉之后,这个配置还留着,npm 会一直尝试连那个已经不存在的端口,反而导致所有 npm 操作都失败。这是配了代理之后最容易碰到的后遗症,遇到 npm 突然全部超时可以先想想是不是这个原因。
查看代理
npm config get proxy
同理查 HTTPS 那一项用 npm config get https-proxy。想一次看全所有配置,可以用 npm config list,加 -l 会把默认值也一起列出来。
删除代理
npm config delete proxy
两项要分别删,HTTPS 那项是 npm config delete https-proxy。不用代理的时候记得删掉,别留着。

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