私有npm包发布安装问题:axios依赖无法从公网获取
你遇到的核心问题是:尽管已经通过webpack把axios打包进了包的dist/index.js产物里,但npm在安装你的私有包时,依然会尝试从Artifactory私有仓库拉取axios——这是因为npm的依赖解析逻辑是基于package.json的dependencies字段,不管你有没有把依赖打包到最终产物中,它都会默认去当前配置的registry查找这些依赖项。
下面给你几个可行的解决方案,你可以根据自身场景选择:
方案1:配置Artifactory虚拟仓库(推荐团队场景)
Artifactory支持创建虚拟仓库,你可以把公网npm仓库(https://registry.npmjs.org)和你的私有仓库合并成一个虚拟仓库。这样当npm请求依赖时:
- Artifactory会优先在私有仓库内查找,找到则直接返回;
- 若私有仓库没有对应依赖,会自动去公网npm仓库拉取并缓存。
配置完成后,你只需把publishConfig和安装时的registry都指向这个虚拟仓库即可,无需修改包的package.json,团队成员也能统一使用,避免每个人单独配置。
方案2:将axios移至devDependencies(适合单个包场景)
你提到axios并非开发依赖,但这里的关键是:你已经通过webpack把axios打包进了最终的dist/index.js里,对于使用你这个包的下游项目来说,根本不需要单独安装axios——它已经包含在你的包代码中了。
这种情况下,axios实际上是你开发打包阶段需要的依赖,而非运行时依赖,完全可以移到devDependencies中:
{ "devDependencies": { "tslint": "^5.15.0", "webpack": "^4.29.6", "axios": "^0.18.0" }, "dependencies": {} }
修改后,npm安装你的包时就不会再去查找axios依赖了,因为dependencies里已经没有这个条目。
方案3:通过.npmrc配置scope级别的registry(适合个人开发场景)
你可以在本地的.npmrc文件中,指定仅@company scope的包从私有仓库拉取,其他包默认从公网npm仓库拉取:
@company:registry=http://artifactory_url registry=https://registry.npmjs.org
之后安装你的包时,无需手动指定--registry参数,直接运行:
npm install @company/package_name
npm会自动从私有仓库拉取你的包,同时从公网npm拉取axios等公共依赖。
额外注意点
- 确认webpack配置没有把axios设为
external——如果配置了externals: { axios: 'axios' },webpack会把axios排除在打包产物之外,这种情况下下游项目依然需要安装axios,就不能使用方案2。 - 若选择方案2,建议在包的README中说明该包已内置axios依赖,避免下游开发者重复安装。
内容的提问来源于stack exchange,提问作者Claudiu Creanga

