在公司项目开发中,我们经常会有相同的业务逻辑或者组件可以复用;但是这些由于安全性,我们又希望将这些代码在内部项目中使用,并不希望公开访问;verdaccio提供了一个搭建npm私有服务器的方式,我们来看下如何搭建以及上传我们自己的依赖包。
介绍及安装
Verdaccio是什么?
Verdaccio
是一个 Node.js创建的轻量的私有npm代理注册源(proxy registry)
通过Verdaccio搭建私有npm服务器有着以下优势:
- 零配置:无需安装数据库,基于nodejs,安装及运行。
- 使用方便:将内部高复用的代码进行提取,方便在多个项目中引用。
- 安全性:仓库搭建在局域网内部,只针对内部人员使用。
- 权限管理:对发布和下载npm包配置权限管理。
谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里
- 加速包下载:将下载过的依赖包进行缓存,再次下载加快下载速度。
Verdaccio是sinopia开源框架的一个fork,由于sinopia作者两年前就已经停止更新,坑比较多,因此Verdaccio是目前最好的选择;首先进行全局安装:
谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里
| npm install -g verdaccio
verdaccio
|
安装后直接输入命令即可运行:
config.yaml
是配置文件的路径,我们可以进行权限等配置;4873是Verdaccio启动的默认端口,支持在配置文件中进行修改;我们再浏览器中打开localhost:4873就能看到他的管理界面了:
通过命令行启动的话,如果终端停止了,那我们的服务器也就停止了,因此一般我们通过pm2启动守护进程。
| npm install -g pm2 pm2 start verdaccio pm2 list
|
这样verdaccio就在后台运行了。
除此之外,我们还可以通过docker来进行安装
| docker run --name verdaccio -itd -v ~/docker/verdaccio:/verdaccio -p 4873:4873 verdaccio/verdaccio
|
谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里
nrm管理镜像源地址
Verdaccio安装好后,我们可以更改npm源为本地地址:
| npm set registry http://localhost:4873/
|
或者针对某个依赖安装时选用自己的源地址:
| npm install lodash --registry http://localhost:4873
|
但是如果我们想再次切换到淘宝或者其他的镜像地址,就不那么方便了;我们可以通过nrm
这个工具来管理我们的源地址,可以查看和切换地址;首先还是进行安装:
安装后我们可以通过nrm add [name] [address]
这个命令来新增一个源地址:
| nrm add localnpm http://localhost:4873/
|
谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里
使用nrm ls
可以查看我们使用的所有源地址,带*
是正在使用的地址;通过nrm use [name]
来切换地址:
配置文件
通过配置文件,我们可以对Verdaccio进行更多的自定义设置,默认的配置文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| # 依赖缓存地址 storage: ./storage # 插件地址 plugins: ./plugins
web: title: Verdaccio
# 认证信息 auth: # 用户账号存储文件 htpasswd: file: ./htpasswd
# 上游链接 uplinks: npmjs: url: https://registry.npmjs.org/
# 包管理 packages: '@*/*': access: $all publish: $authenticated unpublish: $authenticated proxy: npmjs '**': access: $all publish: $authenticated unpublish: $authenticated proxy: npmjs
server: keepAliveTimeout: 60
# 插件开启 middlewares: audit: enabled: true
# 日志管理 logs: - { type: stdout, format: pretty, level: http }
|
Verdaccio默认只能本机访问,我们可以在配置文件最后加入监听的端口,让局域网访问:
| # 监听的端口,不配置这个,只能本机能访问 listen: 0.0.0.0:4873 # 界面默认设为中文 i18n: web: zh-CN
|
所有的账号密码都会保存在htpasswd
这个文件中,我们可以通过在线htpasswd生成器生成加密的密码文件,或者通过命令行的形式来添加用户
谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里
| npm adduser --registry http://localhost:4873/
|
uplinks
上游链接uplinks
表示如果在本地找不到依赖包,去上游哪个地址获取包;我们可以配置多个地址,每个地址都有一个唯一的key值:
| uplinks: npmjs: url: https://registry.npmjs.org/ timeout: 10s yarn: url: https://registry.yarnpkg.com/ timeout: 10s taobao: url: https://registry.npm.taobao.org/ timeout: 10s
packages: '@*/*': proxy: taobao yarn '**': proxy: taobao
|
官方的地址会比较慢,一般建议配置淘宝的地址:配置好上游链接后我们就可以将包的代理指向链接,支持多个链接地址,请求失败时会向后面的链接进行尝试。
令牌
从verdaccio@4.0.0
开始支持配置自定义令牌签名,要启用JWT签名,我们需要将jwt添加到api部分:
| security: api: jwt: sign: expiresIn: 15d notBefore: 0 web: sign: expiresIn: 7d
|
packages包管理
在packages
字段中,我们可以对每个域下面的包进行管理,在verdaccio中有三种身份:所有人、匿名用户、认证(登陆)用户(即”$all”, “$anonymous”, “$authenticated”),默认情况下所有人都有访问的权限(access),认证的用户才有包的发布权限(publish)和撤回权限(unpublish)。
除此之外,我们可以对包进行更进一步的划分,比如公司的包和个人的包,通过@scope
的方式进行访问控制:
| packages: '@company/*': access: $authenticated publish: $authenticated unpublish: $authenticated proxy: npmjs '@my/*': access: $authenticated publish: $authenticated unpublish: $authenticated proxy: npmjs
|
谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里
默认情况下,任何用户都可以通过npm adduser
来向我们的服务器注册用户;如果我们的npm服务器部署在外网的话是不利的,我们还可以通过max_users为-1来禁止注册用户,如果在内网的话,可以设置某个具体的值来限制用户的数量:
| auth: htpasswd: file: ./htpasswd max_users: -1
|
依赖包创建和发布
搭建好了npm私服,我们就可以上传npm包了,我们创建一个utils项目,放一些自己的工具等,首先通过npm init
初始化package.json,然后我们可以对包的信息进行一些修改:
| { "name": "@demo/utils", "version": "1.0.0", "description": "my own utils", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "corner", "license": "ISC" }
|
我们就可以在入口文件index.js
中写代码了,比如这里我们定义了判断环境的几个变量:
| export const UA = window.navigator.userAgent.toLowerCase();
export const isAndroid = UA && UA.indexOf("android") > 0;
export const isIOS = UA && /iphone|ipad|ipod|ios/.test(UA);
export const isWeixin = UA && /micromessenger/i.test(UA);
|
谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里
然后我们登录上面注册的用户,输入用户名、密码以及邮箱等:
也可以通过npm logout
退出登录,以及npm who am i
查看当前登录的用户名;登录成功后就可以将我们的包进行发布了:
谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里
在首页我们登录后就能成功看到刚刚发布的第一个包了,也能给其他同事使用:
我们注意到整个包的入口是main
字段指定的index.js,这是一个es module模块规范的包,但是在commonjs规范的项目中就不能使用了,因此我们可以通过打包工具对其进行打包优化。
我们在深入对比Webpack、Parcel、Rollup打包工具的不同介绍过Rollup比较适合用来打包一个类库,因此这里就选用Rollup进行打包,我们在项目下新建rollup.config.js
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| export default { input: "./index.js", output: [ { format: "cjs", file: "dist/index.commonjs.js", }, { format: "es", file: "dist/index.esm.js", }, { format: "iife", file: "dist/index.bundle.js", name: 'DemoUtils' }, ], };
|
通过rollup将入口文件index.js
打包成commonjs、es module和iife三种规范,然后就在package.json
中分别定义三种规范的文件路径:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| { "name": "@demo/utils", "version": "1.0.2", "description": "my own utils", "main": "dist/index.commonjs.js", "module": "dist/index.esm.js", "jsnext:main": "dist/index.esm.js", "unpkg": "dist/index.bundle.js", "jsdelivr": "dist/index.bundle.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "rollup --config" }, "author": "corner", "license": "ISC", "devDependencies": { "rollup": "^2.54.0" } }
|
谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里
如果还想对我们的包有详细的使用说明等,可以在项目中新建一个README.md文档;build打包后,再次publish发包就能更新线上的依赖包了。