前言

在 2018 年 1 月份的时候,我有开始搭建 npm 私有仓库,那个时候的 Sinopia 也已经停止维护 3 年了,而 verdaccio 还可能不是特别受欢迎,只有 1700 个 star,搭建 npm 私有仓库的工具还有不少。

2018年1月的verdaccio

但在我今天写此文的时候,已经有 8.5K 的 star 了,版本也从 2.7.1 更新到了 4.4,而且基本上没有别的比较好的选择可以替代了。

无营养的话,两年前 sinopia 有 4318 个 star,现在还是增加为 5.3k 了,即便一直没更新,优秀的作品依旧优秀。

安裝使用 Verdaccio(本文是在 Ubuntu 下)

1、安裝 verdaccio

verdaccio 是个发布在 npm 上的命令行工具。可以通过 npm 直接下载安装:

npm install -g verdaccio

2、開啓服務
verdaccio 在文件系统上存储数据,没有额外依赖,而且提供了一套默认配置,我们可以直接启动仓储服务。

在终端直接输入:

verdaccio

启动verdaccio

终端上的日志显示了默认配置文件路径和 verdaccio 工作的地址端口。

3、查看安裝成功效果
浏览器打开http://localhost:4873/ ,页面如下:

verdaccio启动成功画面

不得不说,这比两年前有自我辨识度,之前看起来就像是山寨 npmjs。

4、修改 npm 默认仓库地址

不过目前直接使用的 npm install 还是会去找 npmjs 的,所以,如果需要将默认寻找的地址改为自己的私有仓库,则需要修改 npm 默认的仓库地址,修改如下:

npm set registry http://localhost:4873/

查看有没有修改成功,使用npm get registry,查看显示的地址即可。

5、卸载 verdaccio

当然,如果不想用了,就是一个 npm 下载的工具包而已,直接卸载即可:

npm uninstall -g verdaccio

常规的配置说明

配置文件一般在home/{user}/.config/verdaccio/config.yaml,把{user}替换成你的主机用户名。

简单说明如下(注意与实际配置对比参看):

- storage: 设置托管或缓存包的存放目录
- auth: 权限控制
  - htpasswd: 启用 htpasswd 插件管理权限
  - file: 制定 htpasswd 文件路径,htpasswd 中存储者用户名和加密过的秘钥
  - max\*users: 最多允许注册用户数

- uplinks: 设置外部仓储,如果 verdaccio 找不到请求的包(非 verdaccio 托管),就会查找外部仓储。常见的有
  - {name}: 外部仓储名称
    - url: 访问路径
    - timeout: 超时
    - maxage: 默认值 2m,2m 钟内不会就同样的请求访问外部仓储
    - fail\*timeout: 如果外部访问失败,在多长时间内不回重试
    - headers: 添加自定义 http 头当外部仓储访问请求中,例如 authorization: "Basic YourBase64EncodedCredentials=="
    - cache: 是否启用缓存,默认启用。

      # 常用仓储有
      npmjs:
        url: https://registry.npmjs.org
      yarnjs:
        url: https://registry.yarnpkg.com
      cnpmjs:
        url: https://registry.npm.taobao.org

- packages: 包访问或发布控制
  - {regexp}: 包名匹配正则。
    - access: 访问控制,可选值有
      - \$all(用户不限制),
      - \$anonymous(用户不限制),
      - \$authenticated(所有登录用户),
        username( 用户名,需指定具体用户,可指定多个用户,用户间空格隔开,如 secret super-secret-area ultra-secret-area)。
    - publish: 发布控制,
    - proxy: 代理控制,设置的值必选现在 uplinks 中定义。

    # 常用的包名正则有:

    \*\*            # 匹配任意包
    @\*/\_          # 匹配任意 scope 包
    @npmuser/\_     # 匹配 scope 为 npmuser 的包
    npmuser-\*      # 匹配包名有 npmuser- 前缀的包

    # 包名正则规范通 gitignore 一致,verdaccio 内部使用 minimatch 实现的,如果需要书写更复杂的正则,可以参考 [minimatch](https://www.npmjs.com/package/minimatch/) 文档。

- web: 前端展示页面控制
  - title: 设置页面标题
  - logo: 指定 logo 图片文件路径

- publish: 发布包是的全局配置
  - allow_offline: 在外部仓储离线时是否允许发布。在发布包是 verdaccio 会检查依赖包有效性,这个过程中需要访问外部仓储。

- url_prefix: 设置资源文件路径前缀。默认不需要设置,但如果使用 nginx 代理并改写了请求路径,就需要指定了。
  - listen: 设置服务运行地址端口,默认为 http://localhost:4873
    支持的配置有:
    localhost:4873              # default value
    http://localhost:4873       # same thing
    0.0.0.0:4873                # listen on all addresses (INADDR_ANY)
    https://example.org:4873    # if you want to use https
    [::1]:4873                  # ipv6
    unix:/tmp/verdaccio.sock    # unix socket

- https: HTTPS 证书配置
  - key: path/to/server.key
  - cert: path/to/server.crt
  - ca: path/to/server.pem

- log: 日志控制
  - type: file, stdout, stderr, 其中 stdout 需要同时指定 path
  - level: trace | debug | info | http (default) | warn | error | fatal
  - format: json | pretty | pretty-timestamped

- http_proxy: 设置以 http 形式访问外部仓储时使用的代理
- https_proxy: 设置以 https 形式访问外部仓储时使用的代理
- no_proxy: 不使用代理的请求路径
- max_body_size: 请求时上传的 json 允许的最大值

- notify: 当有包发布成功时,verdaccio 会发送通知。通知实际上是一次 http 请求。支持配置多套通知
  - method: 请求方法 GET,POST 等 HTTP Method
  - packagePattern: 包匹配正则, 这儿为 js 正则,仅当发布的包名匹配正则时才发送通知
  - packagePatternFlags: js 正则标志位,如 i 忽略大小写
  - headers: 自定义请求头
  - endpoint: 请求地址
  - content: handlebar 格式 html 模板,可以使用变量详见 Package Metadata

上传私有包

1、创建包

新建一个文件夹,并npm init,再创建一个 index.js 文件,内容如下图,将此包示例为个人私有包。

私有package示例文件

2、发布包

首先在私有仓库服务器注册一个用户,此处注册成功会自动登入仓库,输入注册语句(之前访问http://localhost:4873上面有显示):

david@ubuntu:~$ npm adduser --registry http://localhost:4873
Username: david
Password:
Email: (this IS public) 183318×××@qq.com
Logged in as david on http://localhost:4873/.
david@ubuntu:~$

如果之前有注册用户,此处可以直接登入

david@ubuntu:~$ npm login --registry http://localhost:4873
Username: david
Password:
Email: (this IS public) 183318×××@qq.com
Logged in as david on http://localhost:4873/.
david@ubuntu:~$

登入成功之后,在刚刚创建的私有包的根目录下,运行发布包命令 npm publish,即可将包发布到私有仓库。

如果没有设定本机默认的 npm 仓库是指定的私有仓库,最好还是指定仓库位置,否则有可能是发布到 npmjs 上去。

david@ubuntu:~/TTT/privatePackage$ npm publish --registry http://localhost:4873
npm notice
npm notice 📦  privatepackage@1.0.0
npm notice === Tarball Contents ===
……省略一些npm notice……
npm notice
+ privatepackage@1.0.0
david@ubuntu:~/TTT/privatePackage$

发布成功之后,再访问http://localhost:4873页面,就能看到已发布的私有包了。

私有仓库可见私有包

当然后续下载使用,就和访问 npmjs 公共包是一样的。

其他常用操作与配置

使用 pm2 启动

verdaccio 毕竟还是一个 nodejs 程序,直接在命令行输入verdaccio启动了,保不齐因为何种原因崩溃。这类守护型工具,常用的就例如 forever 或者 pm2。
以 pm2 为例,用最简单的pm2 start {program}来启动。

全局安装:

npm install pm2 -g

使用 pm2 start。 start 后跟 verdaccio 全局安装的启动地址:

pm2 start {/home/david/.nvm/versions/node/v12.6.0/lib/node_modules/verdaccio/bin/verdaccio}

如果不知道自己 mpnjs 全局安装的 package 的位置,输入npm config ls -l;找到参数 prefix.

例如我的就是prefix = "/home/david/.nvm/versions/node/v12.6.0".
那么我的 start 的路径就是:/home/david/.nvm/versions/node/v12.6.0/lib/node_modules/verdaccio/bin/verdaccio,如下图:

pm2启动verdaccio

浏览器显示公共包

之前有说明,如果你把 verdaccio 私有仓库设为默认仓库,如果某个 package 在私有仓库没有找到,可以设定在链接的外部仓库去寻找,例如我全局安装了一个 doctoc 工具,npm install -g doctoc

david@ubuntu:~$ npm i -g doctoc
/home/david/.nvm/versions/node/v12.6.0/bin/doctoc -> /home/david/.nvm/versions/node/v12.6.0/lib/node_modules/doctoc/doctoc.js
+ doctoc@1.4.0
updated 1 package in 7.961s
david@ubuntu:~$

因为我最开始,已经把 npm 的默认仓库地址改为私有地址了,又在配置文件中默认连接了 npmjs,所以执行这一句之后,首先在 verdaccio 的 storage 的位置找,找不到 doctoc,然后会去 npmjs (配置文件中的 uplinks 参数)去寻找,找到之后下载下来,也存放了一份到 storage 的位置。

现在去配置文件设置的 storage 的地址,应该是可以看到 doctoc 工具包,同样可以看到之前上传的 privatepackage 私有包:

私有仓库下的私有包和公有包

当然,从安装结果可以看到,只是个索引,真实位置还是在 npm 全局安装的位置。

但是访问http://localhost:4873默认是不会显示的,一定程度来讲,共有的包也不必要显示在自家私有仓库内。

如果非要显示,也是可以的,修改显示的列表文件。

找到.verdaccio-db.json文件,默认就在私有仓库的设定 storage 的位置,verdaccio 默认位置~/.local/share/verdaccio/storage/.verdaccio-db.json.打开之后,把需要显示的包名,添加到 list 变量的对象中,
如下图:

修改.verdaccio-db.json文件

然后在重启 verdaccio。如果使用了 pm2,按上述说明作业,直接 pm2 restart verdaccio即可。如果还没有使用 pm2,直接关闭 verdaccio 的命令窗口在启动就好。

再访问http://localhost:4873,就可以看到 doctoc 包了,如下图:

公共包可见

以上实践有效,如果有问题,可提出交流,谢谢。