我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第1篇文章,点击查看活动详情
前言
公司需要发布内部 npm 包,需要搭建一个 npm 私有仓库
需求
没有明确的需求,现有 npm 私有仓库方案也都满足基本需要
调研
搜索一波,大部分的文章都列出以下几种方案
1、cnpm 国内使用较多,流传最广的。有 ts 的重构版本 github start 3.6k + 204(ts 版本)
2、sinopia 已停止维护
3、verdaccio verdaccio fork 于 sinopia github start 13.6k
verdaccio 兼容度很高。
- npm、yarn、pnpm
- doker、nginx、Kubernetes
- 静态网页及权限配置
- 有中文文档
- 有知名项目使用:如 pnpm、
需要的基本一应俱全,具体直接访问官网即可
大概看了下项目流行程度、维护速度、适配广度、配置难度。 最终选用 verdaccio
开始部署
环境准备
1、node(>v16) 不同 verdaccio 版本,要求不同,这里安装 verdaccio5
2、nginx
安装
Node
如需要安装特定版本 node,将以下命令中的 v16.15.1 替换为指定版本即可,详细版本可查看 node 官网
$ cd /usr/local/src
$ wget https://nodejs.org/dist/v16.15.1/node-v16.15.1-linux-x64.tar.xz
$ tar xf node-v16.15.1-linux-x64.tar.xz
$ sed -i '$aexport PATH=$PATH:/usr/local/src/node-v16.15.1-linux-x64/bin' $ ~/.bash_profile
$ source ~/.bash_profile
$ node -v
v16.15.1
Verdaccio
$ npm install -g verdaccio
$ verdaccio -v
v5.13.3
Nginx
使用 yum 安装的版本会比较低,如需高版本 nginx 可搜索相应博客。如你的服务器没有 yum 包管理器,可根据服务器系统搜索该系统的包管理器并安装即可
$ yum install nginx -y
$ nginx -v
nginx version: nginx/1.14.1
配置 Nginx
此处我配置为 https 域名,前提条件是你有 https 证书,也可在网上搜索免费证书。
http 中添加相应配置即可。所有 npm.wooc.top 的地方替换为你的域名
如只配置 http 时,将 location 复制到 80 端口中, 将 80 端口的 return 这一行删除即可
upstream verdaccio_v4 {
server **:4873;
keepalive 8;
}
server {
listen 80;
#填写绑定证书的域名
server_name npm.wooc.top;
#把http的域名请求转成https
return 301 https://$host$request_uri;
}
# Settings for a TLS enabled server.
server {
listen 443 ssl http2 default_server;
server_name **.com;
ssl_certificate /etc/pki/nginx/npm.wooc.top_bundle.crt;
ssl_certificate_key /etc/pki/nginx/npm.wooc.top.key;
ssl on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_session_timeout 5m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_prefer_server_ciphers on;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
proxy_pass http://127.0.0.1:4873/;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
配置文件
我这里只做一些基本配置,需要详细配置的可直接阅读官网文档
$ vi ~/.config/verdaccio/config.yaml
web页面配置
web:
title: npm-cz
权限配置
这里设置禁止用户自己注册,为了更好的进行用户管理,不滥用 npm 账户。
如何添加用户可看下方 配置用户
auth:
htpasswd:
file: ./htpasswd
# -1 为禁止注册
max_users: -1
上游链路
默认为 npm 源, 这里新增了一个淘宝源, 同时更改 packages 中相关联的配置
uplinks:
npmjs:
url: https://registry.npmjs.org/
taobao:
url: https://registry.npmmirror.com
packages:
'@wooc/*':
# scoped packages
access: $all
publish: $authenticated
unpublish: $authenticated
# 该处为你定义的私有库,只查找私有库注册表,所以不必设置上游链路,否则私有包的操作也回查找公共注册库
'@*/*':
# scoped packages
access: $all
publish: $authenticated
unpublish: $authenticated
proxy:
- npmjs
- taobao
'**':
proxy:
- npmjs
- taobao
通知
消息通知的模板可以在官网看详细的规则
notify:
method: POST
headers: [{ "Content-Type": "application/json" }]
endpoint: '这里替换为你想触发的服务的链接,可以是服务器接口、群机器人或者邮箱'
content: '{"body": {"version": 1,"type": "doc","content": [{"type": "paragraph","content": [{"type": "text","text": "New package published: * {{ name }}* Publisher name: * {{ publisher.name }}"}]}]}}'
web 页面语言
支持很多语言,也可以在 web 页面的设置中手动设置,这里设置默认语言为中文
i18n:
web: zh-CN
到这里基本配置已经配置完成。你需要记住以下几个默认文件的路径,当然你也可以自定义
- storage: ./storage 缓存的 npm 包和私有 npm 包发布后的存储位置
- plugins: ./plugins 使用的插件存储的位置
- htpasswd: ./htpasswd 用户密码存储的文件
这些文件都在路径 ~/.config/verdaccio 下,并且默认只有
storage、config.yaml两个文件,其他文件在使用到的时候自己创建或自动创建
配置用户
安装
$ npm install htpasswd-for-sinopia -g
添加用户
1、命令行添加 sinopia-adduser 命令的执行有两个条件
- 密码文件 htpasswd 默认在 ~/.config/verdaccio 目录下,并且需要手动创建
- 需要与 htpasswd 文件在同级目录下
tip:htpasswd 可以自定义路径,并同步修改 verdaccio 配置文件即可
$ cd ~/.config/verdaccio
$ touch htpasswd
$ sinopia-adduser
username:wooc
password:123456
$ cat htpasswd
wooc:{SHA}fEqNCco3Yq9h5ZUglD3CZJT4lBs=:autocreated 2022-07-22T06:55:48.194Z
2、在线创建
htpasswd-for-sinopia 提供了一个 在线网站,可通过手动输入的方式生成,然后手动复制到 htpasswd 文件中即可
此时即可使用 web 页面或命令行进行登陆测试。
启动
一、以默认配置启动
$ verdaccio
访问域名后出现该页面即为成功。默认为英文页面,可点击设置选择中文简体语言
二、持久化运行
官方推荐使用 forever, forever 目前靠社区维护更新,所以 forever 文档推荐 pm2
$ npm install pm2 -g
$ pm2 start `which verdaccio`
使用 npm 私有库
设置镜像源
$ npm set registry https://npm.wooc.top/
发布 npm 项目
1、初始化项目并新建 index.js 文件
$ mkdir wooc
$ cd wooc && npm init -y
$ echo 'console.log("hellow world!")' > index.js
2、package.json
{
"name": "wooc",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "wooc", # 这一项补全参数为作者名称
"license": "ISC"
}
3、登陆
# 如果已经设置镜像源为私有库地址,执行 npm adduser 即可
$ npm adduser --registry https://npm.wooc.top/
npm notice Log in on https://npm.wooc.top/
Username: wooc
Password: 123456
Email: (this IS public) 13170027668@163.com
Logged in as wooc on https://npm.wooc.top/.
4、发布 npm 包
确认在项目根目录
# 如果已经设置镜像源为私有库地址,执行 npm publish 即可
$ npm publish --registry https://npm.cz-robots.com/
npm notice
npm notice 📦 wooc@1.0.0
npm notice === Tarball Contents ===
npm notice 29B index.js
npm notice 218B package.json
npm notice === Tarball Details ===
npm notice name: wooc
npm notice version: 1.0.0
npm notice filename: wooc-1.0.0.tgz
npm notice package size: 295 B
npm notice unpacked size: 247 B
npm notice shasum: 8cee1ea2f05aea82d71766a5c1695752a36d8f48
npm notice integrity: sha512-FSUdOcXnSyZBm[...]spBJSIOzdtRCw==
npm notice total files: 2
npm notice
npm notice Publishing to https://npm.wooc.top/
+ wooc@1.0.0
控制台出现上述信息,说明发布成功
5、查看 web 页面
出现上述信息说明发布成功
6、下载私有包 前置准备
1.项目中配置 .npmrc , 内容为
registry=https://npm.wooc.com
@wooc:registry=https://npm.wooc.com (建议)
2.设置本地 npm 源, 执行命令
npm config set registry https://npm.wooc.com
3.临时使用
npm --registry https://npm.wooc.com
以上三种方式任选其一, 测试私有包的下载是否正常
注意事项
1、私有仓库缓存上游 npm 包并保存私有 npm 包,注意服务器空间预留充足
2、私有仓库可以缓存并加速公司项目 npm 的下载速度,但服务器的带宽消耗也是很大的
3、当公司内部系统并行构建时,npm 服务器会承受较大负载(看服务规模),注意配置充足
Tip: 如果私有库的使用需求不是那么强的话,建议私有库只用在私有包的下载、管理服务,其他的依赖下载指向淘宝源地址即可。
可能出现的问题
1、verdaccio Error: 413 Payload Too Large - PUT request entity too large
包的大小超出限制。
verdaccio 配置问题
默认为 10mb,如需设置可对配置文件的 max_body_size 字段的值进行更改
nginx 配置问题,添加如下配置
http {
...
client_max_body_size 100M;
}
具体可见:stackoverflow
2、package-lock 依赖路径为 ip 而非域名
如果在服务器上开启多核心运行,下载依赖生成的 package-lock.json 文件中的依赖路径会变为私有库的 ip 地址而不是域名,这可能会导致依赖下载时报错。
解决方式:单线程启动