NPM 私仓
npm 私仓可用于提高包的下载速度和保护内部代码,常见的 npm 私仓技术方案有以下几种:
1 | * npm on-site # 缺点是收费,而且 npm 在国内访问慢 |
Sinopia/Verdaccio
Sinopia 是一个零配置的私有的带缓存功能的 npm 包管理平台。使用 Sinopia,不用安装 CouchDB 或 MYSQL 之类的数据库,Sinopia 有自己的迷你数据库,如果要下载的包不存在,它将自动去你配置的 npm 地址上去下载,而且硬盘中只缓存你现在过的包,以节省空间。
Sinopia 特点:
1 | * 不同步拉取 npm 库,占据大量硬盘,没有硬盘被撑爆的问题 |
注意:由于 Sinopia 已经没人维护了,推荐使用 Verdaccio,Verdaccio 是 Sinopia 的 Fork,安装配置基本和 Sinopia 一致。
安装
安装 Sinopia 前,首先要确保已经安装 Node,Linux 下安装 Node 参考具体章节。
1 | npm install sinopia -g |
Sinopia 目录结构如下:
1 | # 程序安装目录(全局安装目录在不同配置下会不一样) |
启动
1 | sinopia |
启动成功后,会有下面两行提示:
1 | warn --- config file - /root/.config/sinopia/config.yaml |
上面一行是 Sinopia 的配置文件所在路径,下面一行是 Sinopia 服务的域名和端口号。然后打开 http://localhost:4873
(可通过 curl),如果能正常访问,说明安装成功。
- 网络访问
默认情况下只能本机 localhost:4873
访问,如果想通过 IP 让其他机器也能访问到,需要在 /root/.config/sinopia/config.yaml
最后一行添加:
1 | listen: 0.0.0.0:4873 |
好了,再试一次 192.168.10.14:4873
,成功访问。如果还不行,可能是防火墙导致,默认情况下防火墙没有开放 4873 端口,需要开放相应的端口。CentOS 6 和 CentOS 7 不一样,以 CentOS 6 为例。
1 | # 进入编辑防火墙配置文件(修改 OUTPUT ACCEPT 下的内容) |
- PM2 做守护进程
Node 服务非常脆弱,一般在实际中使用都会配合守护进程。这里选用 PM2 做守护进程。
1 | # 全局安装 PM2 |
注:更多 PM2 操作指南参考相关文档。另外,如果想要结束 PM2 守护的 Sinopia 进程,可使用以下方法。
1 | pm2 stop sinopia # 参数也可以是具体的 PM2 id(不是 pid),比如 pm2 stop 0 |
也可以手动结束,操作步骤如下。
1 | # 显示所有进程 |
服务端配置
配置文件说明
1 | # |
部分配置字段意义
1 | storage # 仓库保存的路径 |
- auth 配置
max_users: -1 表示我们将最大用户数设置为-1,表示禁用 npm adduser 命令来创建用户,不过我们仍然可以通过当前目录下的 htpasswd 文件来初始化用户。
示例:
1 | yorkie:{SHA}?????????????????=:autocreated 2016-02-05T15:33:46.238Z |
上面的加密算法也很简单,就是简单的 SHA1 哈稀之后再转换成 Base64 输出就好,后面跟着的只是表示时间。
- packages 配置
配置大致分为两个部分,一个是以 @*/*
为开头的,另一个则是通配符 *
。
这个当然就是对 package.json 中的 name 字段进行匹配,比如 @webassemblyjs/ast@1.3.1 将匹配第一个配置,而 express 则匹配第二个。这里这么配置的意义在于:一般团队或者公司的私有项目,会采用不同的权限控制,于是这里借用了 npm 的 scoped name 即 @company 的形式,例如 @weflex/app 即表示 WeFlex 下属的 app 项目了。
接下来,每一个命名过滤器(filter)下都有三项基本设置:
1 | access # 表示哪一类用户可以对匹配的项目进行安装(install) |
对于 1 和 2 的值,我们通常有以下一些可选的配置:
1 | $all # 表示所有人都可以执行对应的操作 |
或者也可以指定对应于之前我们配置的用户表 htpasswd 中的一个或多个用户,这样就明确地指定哪些用户可以执行匹配的操作。
- 为 packages 中
@*/*
字段配置代理源
'@*/*'
下添加 proxy: npmjs
配置,给 scoped packages(npm 官方的定义) 添加代理源,使得能够安装 scoped packages 类型的包(比如 @webassemblyjs/ast@1.3.1)。如果不配置此项,安装基本的包没有问题,但是,安装 scoped packages 包时,比如 webpack,会提示错误:
1 | $ npm install webpack |
这是在安装 @webassemblyjs/ast@1.3.1 这个包时出的问题,sinopia 会提示 404。上面安装的包就是这类的包,常见的有 @angular @type 等。修改配置和代码后,重启 sinopia,这时再次安装就会提示成功。
如果还不成功,可能就是老版本 sinopia 的 bug 导致的(我这版中没出息这个问题),sinopia 每次向 npmjs 请求安装某个包时,请求地址都是转码后再向 npm 请求的,所以会将 @ 转码为 %40,但是 npm 不能识别 %40,所以导致 404 的错误。
这个时候只需要修改 sinopia 中的转码的地方就可以了。转码的文件是 up-storage.js,,修改 up-storage.js 中的 encode 为:
1 | var encode = function (url) { |
用户配置
通过服务器来新建用户。服务器上将 registry 改为 http://localhost:4873:
1 | npm set registry http://localhost:4873 |
然后添加用户:
1 | npm adduser --registry http://localhost:4873 |
这时 htpasswd(config.yaml 同目录) 文件下会生成相应的信息。
客户端使用
配置
1 | npm set registry http://192.168.10.14:4873 # 设置 npm 源 |
1 | npm adduser --registry http://192.168.10.14:4873 # 添加用户。如果不发布 npm 包,是不需要注册和登录的,登录 npm 是为了发布包 |
注:推荐用 nrm 来管理 npm 源。具体的 nrm 操作查看 node 的 npm 相关章节。
安装包
1 | npm install xxx # 选项有 --save (-S)、--save-dev (-D)、-g |
发布包
切换到私有仓库,登录成功之后,就可以执行 npm publish 发布到这个私有 npm 上面啦,发布包的操作跟 npm 官方发布包无差别。
1 | npm login # 登录 npm |
发布包注意事项:
1 | * 包的名称和版本就是你项目里 package.json 里的 name 和 version,author 字段可以显示包的作者,为空则表示匿名 |
使用 Docker 安装 Verdaccio
参考 Docker 安装 Verdaccio 文档。
安装镜像
1 | docker pull verdaccio/verdaccio # 拉取 Verdaccio 的 Docker Image,不指定版本下,拉取的是 latest |
配置镜像
- 新建宿主机目录
1 | # 在宿主机上新建需要挂载到的目录(路径可自选) |
1 | # 拉取配置文件 config.yaml |
注:如果没有将 config.yaml 配置文件放在 /home/kpg/verdaccio/conf/
目录下,会导致浏览器将访问不了,docker run
看不出错误,只有通过 docker logs
查找日志,才能发现问题。
1 | docker ps # 找到 verdaccio container id |
- 设置宿主机目录权限
mkdir verdaccio
创建的目录属主是当前宿主机用户,而每个 docker container 都会运行在自建的用户上。所以要注意挂载目录的权限,要不然 npm adduser
和 npm install
无法写入,提示 500 服务器错误,查看容器日志会有下面这样的提示:
1 | docker logs --tail 20 verdaccio |
1 | docker exec -it verdaccio sh # 进入容器查找容器的用户 ID(进入后 Shell 前缀变成了 ~)。直接在宿主机里面 cat /etc/passwd 查找不到 |
- 挂载宿主机目录
可以在启动时通过 -v
将宿主机目录挂载到容器内目录,也可以通过 docker-compose.yml 来配置 volumes。
- 配置 config.yaml
基本配置参考上面,storage、htpasswd 要指向容器内目录,uplinks 可以使用淘宝 npm 私仓:
1 | storage: /verdaccio/storage |
启动镜像
如果将启动参数放在命令中,做成脚本文件来启动会更加方便(如果用 docker-compose 启动,将参数放在 docker-compose.yml 中也很方便):
1 | docker run -d \ |
-v
用于挂载宿主机的一个目录,:
前面的目录是宿主机目录,后面的目录是容器内目录。
- 一个错误
npm publish
时出现了一个错误:
1 | ... |
查看 Issues 和配置文档发现,By default verdaccio does not allow to publish when the client is offline, that behavior can be overridden by setting this to true.
1 | publish: |
Nginx 反向代理
如果 nginx 直接安装在宿主机,直接 /etc/nginx/conf.d
下新建 nginx.conf 文件,填入以下内容即可:
1 | upstream npm { |
修改客户端 host,然后就可以通过域名访问了。
1 | 192.168.10.101 npm.kpg123.com |