我厂有不少私有仓库,都是日常开发中提炼出来的,在几个项目中共享,比如 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 | 阿里云 |
欢迎吐槽,共同进步