分类
npm

使用 GitHub Registry 托管私有 NPM 源

我厂有不少私有仓库,都是日常开发中提炼出来的,在几个项目中共享,比如 UI、Vuex、网络请求(axios 封装)等。以前的主要形式是使用 npm 安装 GitHub 仓库,即

npm i openresty/some-repo

这样 npm 会自动去 GitHub 查找对应的仓库,然后 clone 下来完成安装。项目中的 .npmignore 文件也会正常生效,安装后的目录会忽略不需要的文件。这样做的好处就是简单,只要仓库存在,安装依赖的系统有足够的权限(比如 ssh key),就能顺利安装。在过去的三年时间里,我们一直都这样做。

但是这样会有一些问题:

  1. package-lock.json 里记录的是 commit hash,只看这个值无法判断版本,npm 也没法使用版本号解决依赖冲突的问题。换言之,比如 A 仓库需要 C 仓库的 1 版本,B 仓库需要 C 仓库的 2 版本,那么就只能同时安装两个版本,因为 npm 无法判断两个版本是否兼容。
  2. 安装的时候要走 git clone,下载量很大,速度很慢,经常被同事吐槽。也会影响 CI 的效率。
  3. 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
阿里云
分类
npm

几步简单的操作解决 `npm audit` vulnerabilities

NPM 是 JavaScript 生态最重要的组成部分,我们的项目中会大量使用 NPM 安装第三方包(安装后就称为“项目依赖”)解决问题。这些第三方包也会带来他们的依赖,最终一个项目里可能安装成百上千个依赖。

有道是:没有完美的代码,代码里一定藏有隐患。所以用的依赖多了,其中有问题的概率也提升了,三五不时的,npm 就会提示我们:found N low/medium/high severity vulnerabilities

npm 提供命令 npm audit fix,理论上可以修复这些隐患,但在实际操作中,以我的经验来看,并不容易生效。我猜测可能是因为依赖间的复杂关系,想彻底解决并升级不太容易。所以我一般是这样做的:

分类
npm

解决新机不能 npm install 私有仓库的问题

前些天换了电脑,从 iMac 27 Retina 2014 late 升级到 iMac 27 2019。关于前因后果,我写在张大妈,感兴趣的同学可以看下:《肉山的电子产品 篇九:机不如新,人不如故——iMac 27 换新记》

换机器要搭环境。有两个选择:

  1. 整盘复制,利用 Time Machine 之类的工具
  2. 自己慢慢搭

考虑到老电脑已经工作了 5 年,经历了小十个系统版本,各种软件删装无数,里面的垃圾很多;再加上我的环境并不复杂,所以我决定自己慢慢搭。

然后遇到一个问题:npm install 会卡住,没有明显的提示信息,只有一段比较可疑:

The authenticity of host 'GitHub.com (1.1.1.1)' can't be established.
ECDSA key fingerprint is SHA256:abcdefg.
Are you sure you want to continue connecting (yes/no)? 

因为项目中用到一些私有仓库的依赖,所以我怀疑是它们的问题。于是我把私有仓库从 package.json 里移除,再安装,成功。看来猜的没错。

然后我手动 git clone 一个项目到本地,clone 的过程中,会看到上面的提示,手动输入 yes,记录目标机器的指纹,视它安全可靠。clone 完成。再把私有仓库依赖加回 package.json,安装,成功。问题解决。

原因:使用 npm 安装 GitHub 仓库作为依赖,实际上等同于使用 git clone 将目标仓库 clone 到 node_modules 里。而 git 协议依托于 ssh 协议。在新机器上安装时,因为没有访问过目标机器,本地不信任目标机器,而 npm 又没有对这个异常做处理,所以就会卡住,不上不下。