存在yarn.lock时安装私有npmjs包失败,求原因与解决方案
我有一个依赖发布到私有npmjs账户的项目,例如依赖@myaccount/first-package。项目根目录下的.npmrc配置如下:
@myaccount:registry=https://registry.npmjs.org/ //registry.npmjs.org/:_authToken=npm_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx always-auth=true
此处使用的认证令牌是从npmjs网页生成的经典令牌,我已尝试过只读令牌和读写令牌。
Yarn配置已正确加载相关设置,yarn config list输出如下:
yarn config v1.22.19 info yarn config { 'version-tag-prefix': 'v', 'version-git-tag': true, 'version-commit-hooks': true, 'version-git-sign': false, 'version-git-message': 'v%s', 'init-version': '1.0.0', 'init-license': 'MIT', 'save-prefix': '^', 'bin-links': true, 'ignore-scripts': false, 'ignore-optional': false, registry: 'https://registry.yarnpkg.com', 'strict-ssl': true, 'user-agent': 'yarn/1.22.19 npm/? node/v18.17.1 linux x64', lastUpdateCheck: 1693395311360 } info npm config { '@myaccount:registry': 'https://registry.npmjs.org/', '//registry.npmjs.org/:_authToken': 'npm_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'always-auth': true }
在首次执行yarn install(此时yarn.lock无对应包条目或不存在)时,包可正常安装到node_modules,且yarn.lock中会添加如下条目:
"@myaccount/first-package@^0.2.36": version "0.2.36" resolved "https://registry.yarnpkg.com/@myaccount/first-package/-/first-package-0.2.36.tgz#340c2c976497bad20d7552e52608ac8d5355e2ab" integrity sha512-45dk+EpASIHs8g+bC+DPD/VeZIbDbL74xJ4viIj+K9Sx0Qv3M8I/EoXvTG1zHxmz/7Itt5AmpwH7/vxlop26IQ==
但删除node_modules后重新执行yarn install,或他人(开发者及CI/CD Docker客户端)拉取含该yarn.lock的代码执行yarn install时,会出现404错误:
error An unexpected error occurred: "https://registry.yarnpkg.com/@myaccount/first-package/-/first-package-0.2.36.tgz: Request failed \"404 Not Found\"".
删除yarn.lock后重新执行yarn install则可正常安装。
yarn install --verbose的输出显示:
成功场景:
verbose 3.066711833 Performing "GET" request to "https://registry.npmjs.org/@myaccount%2ffirst-package". verbose 3.809710167 Request "https://registry.npmjs.org/@myaccount%2ffirst-package" finished with status code 200.
失败场景:
verbose 1.960352751 Performing "GET" request to "https://registry.yarnpkg.com/@myaccount/first-package/-/first-package-0.2.36.tgz". verbose 5.081442544 Error: https://registry.yarnpkg.com/@myaccount/first-package/-/first-package-0.2.36.tgz: Request failed "404 Not Found"
当前环境版本:
Node.js v18.17.1 npm v8.19.2 yarn v1.22.19
补充说明:
- 使用Postman携带认证令牌请求失败URL返回200。
- 使用npm代替Yarn无此问题,但无法更换包管理器。
- .npmrc为全局配置(~/.npmrc)时问题仍存在。
- 无法删除yarn.lock,CI/CD流水线高度依赖它。
- 因项目内部管理需求,需手动添加包到package.json后再执行yarn install。
问题核心在于Yarn v1的锁文件生成逻辑:
- 首次安装时,Yarn会依据
.npmrc的私有仓库配置从npmjs拉取包元数据,但生成yarn.lock时会自动将resolved字段替换为Yarn官方镜像(registry.yarnpkg.com)的地址。 - 私有包仅发布在npmjs私有仓库,并未同步到Yarn官方镜像,因此后续安装直接请求该镜像地址会返回404。
- 读取lock文件时,Yarn会优先使用
resolved中的URL,忽略私有仓库映射配置,同时该请求未携带npmjs的认证令牌(令牌仅配置给了npmjs的registry),进一步导致请求失败。
方案1:强制Yarn使用私有仓库生成lock文件
在项目根目录创建或修改.yarnrc文件,添加以下配置:
registry "https://registry.npmjs.org/" @myaccount:registry "https://registry.npmjs.org/"
配置完成后执行yarn install更新lock文件,此时生成的resolved字段会指向npmjs私有仓库地址,而非Yarn官方镜像,后续安装即可正常拉取私有包。
方案2:批量修改现有yarn.lock的resolved地址
手动或通过脚本批量替换yarn.lock中所有https://registry.yarnpkg.com/@myaccount/为https://registry.npmjs.org/@myaccount/,确保私有包的resolved字段指向正确的仓库地址。
方案3:配置Yarn禁用镜像替换
在.yarnrc中添加以下配置:
disable-self-update-check true registry "https://registry.npmjs.org/"
结合.npmrc的私有仓库配置,Yarn会严格遵循指定的registry,不再将resolved地址替换为Yarn官方镜像。
验证步骤
修改配置后执行以下操作验证:
- (首次验证)删除node_modules和yarn.lock
- 执行
yarn install - 查看yarn.lock中
@myaccount/first-package的resolved字段是否为https://registry.npmjs.org/@myaccount/first-package/-/first-package-0.2.36.tgz格式 - 删除node_modules后重新执行
yarn install,确认无404错误
内容的提问来源于stack exchange,提问作者charith.arumapperuma

