运用Sinopia + PM2建立私有npm仓库

公司的前端项目零散,各个项目间有大量耦合严重的业务代码。基于这个背景,考虑建立一个私有的npm仓库来存储一些常用的工具函数、配置文件、以及一些常用的业务逻辑。本文选用Sinopia来搭建私有的npm仓库。使用PM2来管理Sinopia进程。

登录公司的开发机后,全局安装Sinopia

npm install --global sinopia

然后我们创建一个sinopia的配置文件 用来定义一些参数

$ vim sinopia.config.yaml

首先,我们来看看sinopia的完整的配置文件

其中,比较重要的包含几个配置

  1. users
  2. uplinks
  3. packages
  4. listen

users

这个配置项决定了我们使用什么账户来拥有这个NPM的权限
完整实例为

1 users:
2   admin:
3     # crypto.createHash('sha1').update(pass).digest('hex')
4     password: a94a8fe5ccb19ba61c4c0873d391e987982fbbd3

其中 第二行表示用户名,这边我们使用默认的admin,也可以使用自定义的用户名
第三行表示第四行的password是如何生成的 也就是说,password配置项的密码是由sha1算法生成的,我们只要记住加密前的密码,填写加密后的密文就可以了。

第三行的密码生成是用Nodejs的crypto模块生成的,我们只要把我们的密码作为参数传入update函数(也就是pass变量的位置)生成就可以了

$ node
> crypto.createHash('sha1').update('我想要的密码').digest('hex')
'24c19e31419eebc186b72f8fd85a04de010a5e86' // 生成的密文

将上述密文填入sinopia.config.yaml的users > admin > password字段即可

uplinks

我们的私有库仅有我们自己上传的包 而npm只能注册一个源的机制导致我们必须通过私有库来请求公共的包 比如我们需要安装jQuery,而我们的私有库没有。那么私有库就会去公网上请求。uplinks就是类似一个别名的列表,给公网的包仓库取一个别名,用于更加方便的调用。

uplinks:
  npmjs: // 这边我们定义npm的仓库 也可以定义cnpm等不同的源作为公共仓库
    url: https://registry.npmjs.org/

packages

这是权限相关的配置项 定义可读 可写的范围

packages:
  '*':
    # 允许所有用户读取包,包括未认证用户 (如果使用的是公网ip的机器 需要考虑相关的安全问题,
    # 编者使用的是内网机器,没有这方面太大的问题。)
    # 你可以指定用户名以及组名,需要依赖auth插件以及相关的关键字"$all", "$anonymous", 
    # "$authenticated",本文暂不考虑这种情况,如有需要,可以查看相关文档
    access: $all // 所有用户可读

    publish: admin // admin用户可写,这取决与你的users字段

    # 如果私有仓库中没有想要的包,请求将会代理到对应的公共仓库
    # 取决与定义的uplinks字段
    proxy: npmjs

listen

定义一些监听的端口号,域名等配置
由于默认定义的域名为localhost,这将导致内网无法访问
所以必须至少修改为0.0.0.0或者可用的IP地址

listen:
  0.0.0.0:4873 // IP:端口号
# - localhost:4873            # default value
# - http://localhost:4873     # same thing
# - https://example.org:4873  # if you want to use https
# - [::1]:4873                # ipv6
# - unix:/tmp/sinopia.sock    # unix socket

以上四个就是一些基本的配置项 将这些配置项填入sinopia.config.yaml之后 我们来看看最终输出的文件

  // sinopia.config.yaml
  1 storage: ./storage
  2
  3 listen:
  4     0.0.0.0:4873
  5
  6 users:
  7     admin:
             // crypto.createHash('sha1').update('我想要的密码').digest('hex')
  8         password: 24c19e31419eebc186b72f8fd85a04de010a5e86
  9
 10 packages:
 11     '*':
 12         access: $all
 13         publish: $all
 14         proxy: npmjs
 15
 16 uplinks:
 17     npmjs:
 18         url: https://registry.npm.taobao.org/ // 使用的淘宝源

启动

当我们填写好配置文件之后,键入sinopia -c ./sinopia.config.yaml的命令后 sinopia便运行起来了
在我们自己的浏览器中 键入sinopia运行所在的主机地址以及端口号 x.x.x.x:4873 便能看到私有仓库的界面了

$ sinopia -c ./sinopia.config.yaml // 前台运行
私有仓库的界面.png

点击右上角的login 填入你在配置文件中的账号和密码,就能验证用户名密码是否符合预期

后台启动

现在有个问题 就是直接使用sinopia -c ./sinopia.config.yaml命令启动 那么sinopia程序就只在前台启动 如果退出进程或者退出命令行 sinopia就会停止运行,这无法接受。 所以我们将使用PM2工具来启动sinopia

PM2是一个进程管理工具 使用PM2 您的应用将达到持久化,在崩溃和机器重启时自启动。所有的应用都被守护进程,例如,在后台持续运行。PM2相关本文将不再介绍 具体可查看PM2官方文档

使用PM2管理sinopia非常简单 安装PM2后运行sinopia脚本即可

首先 安装PM2

$ npm install pm2 -g
$ pm2 -v // 安装完毕后检查是否安装成功

然后 创建一个sinopia运行脚本

$ vim sinopia.start.sh

// sinopia.start.sh
1 sinopia -c ./sinopia.config.yaml

保存退出后 使用pm2指令来运行sinopia

$ pm2 start ./sinopia.start.sh --name="sinopia" // 给这个进程取一个sinopia的别名
$ pm2 list // 如果看到启动的sinopia那么说明后台启动成功了。
┌────────────────┬────┬─────────┬──────┬───────┬────────┬─────────┬────────┬──────┬───────────┬──────┬──────────┐
│ App name       │ id │ version │ mode │ pid   │ status │ restart │ uptime │ cpu  │ mem       │ user │ watching │
├────────────────┼────┼─────────┼──────┼───────┼────────┼─────────┼────────┼──────┼───────────┼──────┼──────────┤
│ sinopia        │ 10 │ N/A     │ fork │ 1629  │ online │ 0       │ 2D     │ 0%   │ 1.2 MB    │ root │ disabled │
└────────────────┴────┴─────────┴──────┴───────┴────────┴─────────┴────────┴──────┴───────────┴──────┴──────────┘

发布包 && 获取包

当我们配置好服务端的npm私有仓库后,我们需要配置本地的机器来接入私有的仓库

获取包

由于获取包的权限是所有人可读
那么我们仅需将npm的源修改为私有仓库的地址即可

$ npm config set registry http://xx.xx.xx.xx:4873

配置好之后,依赖的安装将走内网的仓库,如果内网的仓库没有需要的包 那么将会代理到配置的公共仓库中。

发布包

本段仅介绍私有仓库的发布相关 涉及具体发布npm包的流程不再赘述

上传包的权限为x用户(x用户即为配置文件中的users字段配置的信息) 那么就需要先登录后在上传

如果没有修改过源 那么同样得修改npm仓库源 当然 配置过一次就可以了

$ # npm config set registry http://xx.xx.xx.xx:4873 // 如果本机没配置过 那么执行一次
$ npm login // 系统将弹出输入用户名以及密码的提示
Username: admin // 取决与你填写在配置文件中的users字段
Password: 我想要的密码 // 仅用于事例,实际不展示密码 密码为配置文件中password字段加密前的明文

登录成功后 你就拥有推送包到私有仓库的权限了

总结

搭建私有仓库其实并非重头,如何考虑、设计通用优雅的私有包才是重中之重。
编者在开发包的过程中,考虑了大量开发中遇到的问题。最终的方案为使用Typescript开发各个包并编写大量@types文件来提升开发体验。如果有机会,可以再聊聊相关的话题。

你可能感兴趣的:(运用Sinopia + PM2建立私有npm仓库)