Verdaccio 工具搭建 NPM 私有仓库

3,975 阅读4分钟

前言

在构建项目过程中,为了提高项目的复用性和可维护性,常用的技术方案是抽离一个npm包,例如将 SDK 库、项目脚手架、前端组件库等依赖包资源放在 npm 上管理,因为涉及到源码和敏感数据,从安全性和使用简便方面考虑,比较稳妥快捷的方式是搭建一个内部 npm 私有仓库在公司内网中访问。

npm 私有仓库技术选型

常用的 npm 私有仓库框架:

  • Nexus:是 Java 社区的一个方案,可以用于 Maven、npm 多种类型的仓库,界面比较丑

  • Sinopia:是基于 Node.js 构建的,已经不维护了

  • Verdaccio:是 forked Sinopia 进行改造的;Sinopia 和 Verdaccio 比较偏向于一个零配置、轻量型的私有 npm 模块管理工具,不需要额外的数据库配置,它内部自带小型数据库,支持私有模块管理的同时也支持缓存使用过的公共模块,发布及缓存的模块以静态资源形式本地存储

  • cnpm:支持静态配置型用户管理机制,以及分层模块权限设置,可以实现公共模块镜像更新以及私有模块管理,支持拓展多种存储形式,相对的数据库的配置较多,部署过程略复杂,是淘宝及多家大型公司搭建内部私有 npm 仓库选择的方案

  • cpm: github.com/cevio/cpm

  • npmfrog: github.com/dmstern/npm…

基于团队内使用的考虑,使用 Verdaccio 构建成本比较低,后期也好维护

Verdaccio 搭建

Verdaccio 是一个开源的、轻量级的私有 npm 仓库管理器,允许开发团队在本地环境中搭建一个专属的 npm 仓库,用于存储和管理项目的依赖包,有利于在公司内部管理多个自定义包,确保稳定性和安全性。

搭建流程首先在本地环境安装和测试,跑通流程后,在线上服务器部署安装

搭建和配置

全局安装 verdaccio 包

npm i -g verdaccio

服务器上报 grywarn 权限的错,可以加上 --unsafe-perm

配置文件路径是 ~/.config/verdaccio/config.yaml,可以编辑,例如加入淘宝源

# config.yaml
uplinks:
  npmjs:
    url: https://registry.npmjs.org/
    # 其他设置 ...
  taobao:
    url: https://registry.npm.taobao.org/
    # 其他设置 ...
# 其他设置 ...
packages:
  '@*/*':
    access: $all
    publish: $authenticated
    unpublish: $authenticated
    proxy:
      - npmjs
      - taobao
    # 其他设置 ...
  '**':
    access: $all
    publish: $authenticated
    unpublish: $authenticated
    proxy:
      - npmjs
      - taobao
    # 其他设置 ...

access 是访问权限控制,总共有三种身份:所有人(all)、匿名用户(all)、匿名用户(anonymous)、认证(登陆)用户($authenticated)。

verdaccio 默认端口是 4873,部署访问不到可以查看防火墙和开放端口

firewall-cmd --state                 # 先查看防火墙状态,
service firewalld start              # 开启防火墙:
firewall-cmd --zone=public --add-port=4873/tcp –permanent  # 开放4873端口
firewall-cmd --reload                # 重新载入
firewall-cmd --zone=public --query-port=4873/tcp    # 查看是否添加成功

如果访问线上启用端口前面显示的是 localhost:4873,可以编辑配置文件,在最后一行新增 listen 0.0.0.0:48730.0.0.0 表示当前主机的 IPV4 地址;之后再重启服务,在浏览器输入服务器 IP 加端口就可以访问

启动

verdaccio # 启动 verdaccio

看到 log 信息,说明已经启动成功

在浏览器中访问 http://localhost:4873/,可以看到一个图形化管理界面

set registry 设置源

有私有源、npm、yarn源,为了方便源管理,切换 npm 源,安装一个源管理工具 nrm

全局安装 nrm

npm i -g nrm 

添加本地源地址,然后切换到当前源

nrm add localnpm http://localhost:4873/
nrm use localnpm

查看所有源信息

nrm ls

源管理常用命令

nrm add name http://verdaccio.xxx/  # 新增源信息 
nrm del  name  # 删除源信息
nrm use name # 切换源信息
nrm ls # 查看当前源信息

创建用户

执行下面命令,添加账号,输入名称、密码、邮箱

npm adduser --registry http://ip地址:4873/

刷新一下页面,登录

命令行验证是否登录成功,执行下面命令,出现你的用户名表示成功了

npm who i am

发布 package 包测试

1、创建一个测试包

npm init -y

2、登录 npm 账号(如何没有账号,根据上面创建账号)

3、执行 npm publish 发布命令(每次发布,版本号不能相同)

发布后,可以看到包的信息

如果想删除组件包,执行下面命令

npm unpublish npm-test --force 删除组件

pm2 守护 verdaccio 进程

安装 pm2

npm install -g pm2 --unsafe-perm

使用 pm2 启动 verdaccio

pm2 start verdaccio

查看 pm2 守护下的进程 verdaccio 的实时日志

pm2 show verdaccio

nginx 配置

server {
	listen 443 ssl http2;
	server_name registry.xxx.com;
  
    # ssl
    ssl on;
    ssl_certificate cert.crt;
    ssl_certificate_key cert.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1.2 TLSv1.1 TLSv1; #SSL协议
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;#SSL加密算法
    ssl_prefer_server_ciphers on;

	location / {
        proxy_set_header    Host $host;
        proxy_set_header    X-Real-IP $remote_addr;
        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header    X-Forwarded-Proto $scheme;
        proxy_pass          http://127.0.0.1:4873/;
        proxy_read_timeout  600;
        proxy_redirect off;
	 }

	 location ~ ^/verdaccio/(.*)$ {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_set_header X-NginX-Proxy true;
        proxy_pass http://127.0.0.1:4873/$1;
        proxy_redirect off;
    }
}

pm2 常用命令

  • pm2 -ls 列出当前被 pm2 管理的所有进程
  • pm2 stop vardaccio 关闭进程
  • pm2 restart verdaccio 重启进程
  • pm2 delete verdaccio 删除某个进程
  • pm2 start verdaccio 启动某个进程

参考配置文件

# 仓库的包默认存储的位置,默认是不存在的,当发布私有包之后会在 /root/.config/verdaccio 中存在
# path to a directory with all packages
storage: ./storage
# path to a directory with plugins to include
plugins: ./plugins

web:
  # 网页 title
  title: Verdaccio
  # comment out to disable gravatar support
  # gravatar: false
  # 包的排序 asc 降序 desc 升序
  # by default packages are ordercer ascendant (asc|desc)
  # sort_packages: asc
  # 是否开启暗黑模式
  # convert your UI to the dark side
  # darkMode: true
  # 网页 logo
  # logo: http://somedomain/somelogo.png
  # 网页 favicon
  # favicon: http://somedomain/favicon.ico | /path/favicon.ico
  # 网页最大连接数
  # rateLimit:
  #   windowMs: 1000
  #   max: 10000

# translate your registry, api i18n not available yet
# i18n:
# 国际化相关,同样404了。
# list of the available translations https://github.com/verdaccio/ui/tree/master/i18n/translations
  # 支持 zh_CN
  #   web: en-US

auth:
  # 注册用户的信息存放位置
  htpasswd:
    file: ./htpasswd
    # Maximum amount of users allowed to register, defaults to "+inf".
    # You can set this to -1 to disable registration.
    # 默认可注册的用户是无限的,如果修改为 -1 则是不允许注册;限定用户方法如下
    # 1,先注册 n 个用户,然后修改配置文件为 -1,后续不允许注册
    # 2,开个 n 个用户注册接口
    # max_users: 1000

# a list of other known repositories we can talk to
# 如果私有库没有的话,去查找以下库。
uplinks:
  npmjs:
    url: https://registry.npmjs.org/

packages:
  # @*/ 是包的作用域 例如 @vue/cli 那么 @vue 则是这个包的作用域,前缀一般都是某个组织或者说某个公司,证明这是个内部包
  '@*/*':
    # scoped packages
    access: $all
    publish: $authenticated
    unpublish: $authenticated
    # 如果私有库没有的话,去 npm 查找查找库。
    proxy: npmjs
  # 普通的 npm 包
  '**':
    # 允许所有用户发布和访问包
    # allow all users (including non-authenticated users) to read and
    # publish all packages
    #
    # 也可以指定指定 @xxx/xxx 类似的作用域
    # you can specify usernames/groupnames (depending on your auth plugin)
    # $all 所有人 $anonymous 只有匿名者可以操作(基本没用) $authenticated 认证用户(通过npm adduser 添加的用户。
    # and three keywords: "$all", "$anonymous", "$authenticated"
    access: $all

    # allow all known users to publish/publish packages
    # (anyone can register by default, remember?)
    publish: $authenticated
    unpublish: $authenticated

     # if package is not available locally, proxy requests to 'npmjs' registry
    proxy: npmjs


server:
  keepAliveTimeout: 60

middlewares:
  audit:
    enabled: true

# log settings
logs: { type: stdout, format: pretty, level: http }


listen: 0.0.0.0:4873

参考文档