分类: npm

  • 使用 GitHub Registry 托管私有 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 audit` vulnerabilities

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

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

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

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

    (更多…)
  • 解决新机不能 npm install 私有仓库的问题

    解决新机不能 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 又没有对这个异常做处理,所以就会卡住,不上不下。