npm 私有包

npm 包安装失败

今天发现 Jenkins 在构建项目时报错 npm WARN tar ENOENT: no such file or directory, open ...,于是尝试本地删除 node_modules 重新安装,同样复现以上问题:

$ npm install
npm WARN tar ENOENT: no such file or directory, open '/Users/keqingrong/BoncProjects/cade-components/node_modules/.staging/@lerna/batch-packages-24a0b652/package.json'
npm WARN tar ENOENT: no such file or directory, open '/Users/keqingrong/BoncProjects/cade-components/node_modules/.staging/@lerna/listable-e23bdc9a/package.json'
npm WARN tar ENOENT: no such file or directory, open '/Users/keqingrong/BoncProjects/cade-components/node_modules/.staging/@lerna/link-ea710c0e/package.json'
...
npm ERR! Maximum call stack size exceeded

npm 使用过程中遇到这种玄学问题,通常都是祭出 rm -rf node_modules package-lock.json 大法。

$ npm install -g npm
$ rm -rf node_modules package-lock.json
$ npm install

然而……安装时又出现了新的问题。

安装私有 npm 包

$ npm install
npm ERR! code ETARGET
npm ERR! notarget No matching version found for @webassemblyjs/helper-wasm-bytecode@1.8.5
npm ERR! notarget In most cases you or one of your dependencies are requesting
npm ERR! notarget a package version that doesn't exist.
npm ERR! notarget 
npm ERR! notarget It was specified as a dependency of '@webassemblyjs/ast'
npm ERR! notarget

这也是日常使用中非常常见的 Nexus Repository Manager 3 同步问题。

指标不治本的方法是暂时将 package.json 中的私有包移除,使用 npm 官方源重新安装:

$ npm install --registry=https://registry.npmjs.org/

安装完成后,恢复 package.json 中的私有包,再使用公司内部 registry 源安装。

一劳永逸的方法是配置 .npmrc,私有包通过公司内部 Nexus 仓库下载,公有包从 npm 官方源下载。

$ npm config set registry https://registry.npmjs.org/
$ npm config set @myorg:registry https://nexus.example.com/repository/npm-group/
registry=https://registry.npmjs.org/
@myorg:registry=https://nexus.example.com/repository/npm-group/

如果使用 yarn,需要设置 always-auth=true,避免安装私有包出现 401 鉴权问题。

这里需要对私有包的命名有要求,建议统一命名为 @scope/name 形式,便于做权限控制。

发布私有 npm 包

如果没有登录,则需要先登录到对应的 registry,输入个人账号密码。

$ npm adduser --registry=https://nexus.example.com/repository/npm-hosted/ --scope=@myorg

或者(npm loginnpm adduser 的别名):

$ npm login --registry=https://nexus.example.com/repository/npm-hosted/ --scope=@myorg

发布私有包时,默认发布到 .npmrc 中配置的 scope 对应 registry。

如果希望指定不同的 registry,需要参照 .npmrc 配置进行覆盖。

命令行参数使用较为灵活:

$ npm publish --@myorg:registry=https://nexus.example.com/repository/npm-hosted/

如果使用固定配置,也可以在 package.json 文件中添加 publishConfig 字段:

{
  "private": true,
  "publishConfig": {
    "@myorg:registry": "https://nexus.example.com/repository/npm-hosted/"
  }
}

发布时,直接运行 npm publish

相关链接