DEBUG.WIKI
OnlineSIM:在线接收短信,虚拟号码租用
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →
野草云;香港 200Mbps 峰值;不限月流量 · BGP VPS;查看套餐 →

npm 代理在 /npm 下,偏偏 npm 包下载 404:检查路径少了一层

当仓库路径与包名恰好相同,replace-registry-host 可能把包路径误认为已有仓库前缀。比对 packument、tarball 和锁文件地址,局部修正下载入口。

私有 npm 代理挂在 /npm/ 下,大多数包能装,名为 npm 的包却在下载 tarball 时报 404 或 405。若锁文件来自公共 registry,检查实际请求是不是少了一层 /npm。

npm 12.2.1 有一个具体条件:默认的 replace-registry-host=npmjs 把公共下载地址改写到带路径的 registry 时,可能把“包名恰好等于仓库路径段”误判为已经带前缀。npm 11 的相关路径也需按实际版本核对,不能把所有代理 404 都归到这里。

对比元数据请求和 tarball 请求

以下是结构示例,不表示应配置本地服务:

配置 registry: http://localhost:3080/npm/
公共 resolved: https://registry.npmjs.org/npm/-/npm-11.19.1.tgz
正确代理路径: /npm/npm/-/npm-11.19.1.tgz
异常请求路径: /npm/-/npm-11.19.1.tgz

第一段 npm 是代理挂载路径,第二段才是包名。元数据请求 /npm/npm 正确,并不能证明 tarball 请求也正确。把包名换成一个不相关名字后能装,也不代表令牌或代理本身都坏了。

先查第一条失败请求、锁文件中对应包的 resolved、当前 registry 和改写策略。地址已正确而返回 401 时,应处理认证范围;地址正确仍 404 时,继续查代理是否确实提供该版本及 tarball,不能盲目补路径。

只修明确错误的下载入口

12.2.1 的正式改写代码在 host-only 分支里检查 pathname 是否已有 registry 路径前缀。公共源里 /npm/-/... 的包路径恰好通过检查,因而没有再加代理前缀。

若代理允许提供该 tarball,可以在受控分支为这一个锁定包确认真实下载地址,把对应 resolved 改到批准的完整代理 URL。示例的正确地址包含 /npm/npm/-/...;实际必须使用自己的 registry 和经过核对的路径。保存原锁文件,保留版本与 integrity,不批量替换其他包的路径或删除完整性校验。

更适合团队长期使用的方式,是在审定 npm 版本、registry 与配置下重新生成相关锁定信息,并逐条审查版本及 URL 差异。需要避免改写策略时,也只能在组织允许原下载源、认证范围准确的前提下局部评估;不能为了绕过代理错误就把整个 CI 流量改到未经批准的外部源。

全局安装第三方工具时,错误还可能来自它自带的 shrinkwrap。项目根的锁文件修正未必能影响那份依赖,应确认实际被读取的文件和安装入口,不直接修改全局缓存里的临时副本。

验收必须看到正确 tarball 与相同版本

在独立工作目录按原锁文件安装方式检查,确认元数据和 tarball 都请求批准的完整路径,安装包版本与完整性仍符合锁定信息,再执行原工具或构建入口。

npm ci 会重建已有依赖目录,不在保留手工修改的目录里验证。安装能退出还不足以结束:若为绕行重新解析了锁文件,核对没有顺带升级依赖。回退时恢复配置和审定锁文件,不保留只在某台代理上偶然可用的错误地址。