vv13
博客关于我

如何搭建一个私有 npm 仓库?

npm 是 Node.js 的包管理器工具,也广泛应用于前端模块化开发,我们通过将代码以一定的模块化规范封装起来,上传到公共的 npm 官方仓库中,就可以方便的对代码进行共享与复用,此外也有许多镜像站会实时地对官方仓库进行资源同步,比如国内的淘宝源。

当我们需要使用 npm 仓库对公司业务代码进行复用封装,或者模块内部包含了一些敏感信息,此时公共仓库就不适用了,我们需要搭建自己的私有 npm 仓库。

Verdaccio 是一个轻量级的私有 npm 仓库搭建工具,它功能强大,文档完善,使用起来也非常便捷,接下来我会对它进行一些简单的使用介绍。

快速开始

安装 Verdaccio 你只需要一条命令:

npm i -g verdaccio

然后运行命令 verdaccio

$ verdaccio
 warn --- config file  - /Users/vv13/.config/verdaccio/config.yaml
 warn --- Verdaccio started
 warn --- Plugin successfully loaded: verdaccio-htpasswd
 warn --- Plugin successfully loaded: verdaccio-audit
 warn --- http address - http://localhost:4873/ - verdaccio/4.4.2

此时可将 npm 工具的 registry 更换为我们的私有 npm:

$ npm set registry http://localhost:4873/

为了避免全局设置执行一些一次性命令,我们也可以在使用时指定 registry,比如:

  • 从私有 npm 安装依赖:NPM_CONFIG_REGISTRY=http://localhost:4873 npm i
  • 推送到私有 npm:npm publish --registry http://localhost:4873

现在你可以使用一下基本的推送、安装依赖等命令,通过 http://localhost:4873 可访问在线 Web 管理服务地址。

基本定制

为了将私有 npm 集成到业务开发流程中,我们还需要做一些定制化操作,在此带各位简单使用下。

持久化配置文件

当直接运行 verdaccio 时,它使用的默认配置肯定无法满足我们的预期,我们期望将配置文件持久化,并指定特定的端口、认证信息、储存位置等信息,这样更加便于系统的管理。

首先我们进行初始化 verdaccio 文件夹:

$ mkdir verdaccio
$ cd verdaccio && touch config.yaml
Authentification

系统默认权限认证使用htpasswd,我们对其进行初始化,创建一个加密文件htpasswd,其中管理员账号密码为admin/123

htpasswd -bc htpasswd admin 123

然后编写配置文件:

auth:
  htpasswd:
    file: ./htpasswd
    max_users: 100

其中 max_users 代表最大的用户数。

uplinks

uplinks 可用于设置上游地址,也就是说,在私有库中不存在指定 npm 包时,可通过上游仓库地址去查找相应资源。

在此将官方源地址加入上游链接中:

uplinks:
  npmjs:
    url: https://registry.npmjs.org/
Storage

用于指定私有仓库的存放路径,当你将 npm 推送到仓库中,或是从上游仓库查找 package 时,都会将最终的 package 存放到此目录中。

我们将 storage 指定为当前目录:

storage: ./storage
Logger

这里使用默认的 stdout 输出管道。

logs:
  - {type: stdout, format: pretty, level: http}
Package

packages 字段用于定义仓库中指定 package 的访问权限、推送权限以及上游代理信息,对于我们的私有 npm,我选择使用前缀@vv13npm-scope 用于区分私有库与非私有库,在获取 scope 包时需要认证信息,并不去请求代理,除此之外的包可任意访问,并链接到上游库:

packages:
  '@vv13/*':
    access: $authenticated
    publish: $authenticated

  '**':
    access: $all
    publish: $all
    proxy: npmjs

至此,config.yaml就编写完了,现在来启动一下服务并进行验证:

verdaccio --config ./config.yaml

首先,使用账号(admin / 123)进行登录,邮箱随便填:

$ npm login --registry http://localhost:4873

创建一个 test 仓库:

$ mkdir test && cd test && npm init -y

将 package.json 中的 name 改为@vv13/test,然后推送到远程库:

$ npm publish  --registry http://localhost:4873

此时应该提示推送成功,但需要注意的是,publish 是需要权限认证的,因为在本机执行的配置验证,因此在 ~/.npmrc 文件中已经生成好了authToken,若是在服务器中进行部署,则需要将服务器上的 token 信息放到项目中的 .npmrc 文件,方可进行 pull 代码。

容器化部署

通过持久化配置文件,我在启动本机服务时进行了一些配置项的微调,接下来的这一步即是通过容器化的形式部署到内网服务或外网机器中,以此来实现易于管理配置的私有仓库服务,给前端工程赋能。

以下为根据以上配置需要编写的docker-compose.yml文件:

version: '3.1'

services:
  verdaccio:
    image: verdaccio/verdaccio:4
    container_name: "verdaccio"
    networks:
      - node-network
    environment:
      - VERDACCIO_PORT=4873
    ports:
      - "4873:4873"
    volumes:
      - "./storage:/verdaccio/storage"
      - "./conf:/verdaccio/conf"
networks:
  node-network:
    driver: bridge

我们需要将 config.yaml 与 htpasswd 文件都移动到 conf 文件夹下,然后执行启动服务脚本:

$ mkdir conf && mv config.yaml htpasswd conf && docker-compose up -d

当本地能正常运行后,我们期望将它迁移到内网服务器上直接部署,由于数据储存采用的是 Local Storage 的方式,迁移起来也十分方便,我们分两部进行验证:

  1. 将 verdaccio 文件夹推送到服务器上,并运行服务、配置网关。
  2. 尝试在 node 工程中通过私有 npm 进行安装私有包。

服务部署那一块无需多言,我们先直接从本地的 node 工程中拉取私有库的 package:

$ npm i @vv13/test --registry=http://xx.xx.xx.xx:4873/
npm ERR! code E401
npm ERR! Unable to authenticate, your authentication token seems to be invalid.

由于我们在 config.yaml 中指定了私有 npm access 权限为 authenticated,因此我们需要将认证信息加入到本地 npm 配置中。

查阅 npmrc 文档可知,首先我们可以为指定 scope 权限的包指定特定的registry 地址,这样就不会影响其他包的正常安装:

@vv13:registry=http://xx.xx.xx.xx:4837

除此之外,我们还需要认证的 token,首先通过 npm login --registry http://xx.xx.xx.xx:4873 进行登录认证,认证成功后会在 ~/.npmrc 中生成一行代码,我们新生成的代码加入到项目中的 .npmrc:

@vv13:registry=http://xx.xx.xx.xx:4873/
//xx.xx.xx.xx:4873/:_authToken="zbwxk0hX3yrLA7IAU5mzKA=="

此时,再执行 npm i @vv13/test即可安装成功。

参考