我厂有不少私有仓库,都是日常开发中提炼出来的,在几个项目中共享,比如 UI、Vuex、网络请求(axios 封装)等。以前的主要形式是使用 npm 安装 GitHub 仓库,即
npm i openresty/some-repo
这样 npm 会自动去 GitHub 查找对应的仓库,然后 clone 下来完成安装。项目中的 .npmignore 文件也会正常生效,安装后的目录会忽略不需要的文件。这样做的好处就是简单,只要仓库存在,安装依赖的系统有足够的权限(比如 ssh key),就能顺利安装。在过去的三年时间里,我们一直都这样做。
但是这样会有一些问题:
package-lock.json 里记录的是 commit hash,只看这个值无法判断版本,npm 也没法使用版本号解决依赖冲突的问题。换言之,比如 A 仓库需要 C 仓库的 1 版本,B 仓库需要 C 仓库的 2 版本,那么就只能同时安装两个版本,因为 npm 无法判断两个版本是否兼容。安装的时候要走 git clone,下载量很大,速度很慢,经常被同事吐槽。也会影响 CI 的效率。 git 仓库里要提交编译后的代码,一方面浪费时间和空间,另一方面大量编译后的代码也影响 code review
所以,考虑之后决定改用 GitHub Registry。GitHub Registry 是 GitHub 提供的私有源,感兴趣的同学可以访问这个页面 了解详情。这个服务需要收费,不过我厂本来就是 Team 用户,额度比较富裕,所以并没有阻力。
经过一段时间的摸索,终于搞成了,下面简单说一下做法。
对依赖项目
修改 package.json,把项目名称改成 @openresty/some-repo,即“@公司名/仓库名”。然后增加 publishConfig 字段,设置源为 GitHub registry:
{
"publishConfig": {
"registry": "https://npm.pkg.github.com/"
},
}
接下来,正常使用 npm publish 发布依赖即可。不过在发布之前,最好使用 .npmignore 忽略掉开发时的源文件和配置文件,一方面这些文件对于其它项目的开发没有价值,另一方面无论是存储还是下载消耗流量,都要收费,能省则省嘛。
对业务项目
因为这些依赖仓库都是私有项目,所以我们先得解决身份认证的问题。GitHub 提供了 Personal access tokens 方式,生成 token 后,添加到 ~/.npmrc 文件即可:
//npm.pkg.github.com/:_authToken=<TOKEN>
接下来,在业务项目中,添加 .npmrc 文件,指名依赖源:
registry=https://registry.npmjs.org/
@openresty:registry=https://npm.pkg.github.com
这段配置分两部分:其它域的依赖,直接从 npm 的源下载;@openresty 域下的依赖,从 GitHub Registry 下载。
最后,正常使用 npm i @openresty/some-repo 安装依赖即可。
最后的最后附上修改前后的效果对比,可以看出,改造后效果明显:
国内 修改前 real 0m39.543s user 0m17.768s sys 0m3.944s 阿里云 修改后 real 0m16.450s user 0m15.204s sys 0m3.380s 阿里云 国外 修改前 real 0m49.350s user 0m22.352s sys 0m4.144s 阿里云 修改后 real 0m30.807s user 0m15.780s sys 0m3.936s 阿里云