cnpm 是企业内部搭建 npm 镜像和私有 npm 仓库的开源方案,当企业业务逻辑相关的模块可能不适合开源。这部分私有的模块就可以放在私有 npm 仓库中来管理和维护。
以下为搭建私有 npm 的详细步骤,这里使用了由阿里的团队开源的 [cnpmjs.org][href1] ,主要分为 Server 端的配置和 Client 的配置:
Server
Server 端主要有 cnpm, mysql, nginx 的配置。
环境:
```# system
$ cat /etc/redhat-release
CentOS Linux release 7.1.1503 (Core)
node
$ node -v
v6.9.1
npm
$ npm -v
3.10.9
nginx
$ nginx -v
nginx version: nginx/1.9.9
mysql
$ mysql -u yourname -p
$ mysql> \s;
Server version: 5.5.38-log MySQL Community Server (GPL)
server ip
192.168.33.10
<h3>安装:</h3>
```# clone from github
$ git clone git://github.com/cnpm/cnpmjs.org.git $HOME/cnpmjs.org
$ cd $HOME/cnpmjs.org
# init mysql
$ mysql -u yourname -p
mysql> create database cnpmjs;
mysql> use cnpmjs;
mysql> source docs/db.sql
配置:
```$ pwd
/home/xxx/cnpmjs.org
$ vim config/config.js
module.exports = {
debug: false,
// 添加自己的私有前缀,可以有多个,必填
scopes: ['@test'],
enableCluster: true,
// mysql,必填
database: {
db: 'cnpmjs',
username: 'username',
password: 'password',
dialect: 'mysql',
host: '192.168.33.10',
port: 3306,
pool: {
maxConnections: 10,
minConnections: 0,
maxIdleTime: 30000
},
logging: !!process.env.SQL_DEBUG,
},
mail: {
enable: false,
appname: 'appname',
from: 'from',
service: 'service',
auth: {
user: 'user',
pass: 'pass'
}
},
// 日志目录,cnpm 的运行日志,必填
logdir: '/data/logs/cnpm/node_logs/',
nfs: require('fs-cnpm')({
// package 存放目录,必填
dir: '/data/logs/cnpm/node_nfs/',
}),
// 上传目录,必填
uploadDir: '/data/logs/cnpm/node_modules/',
enablePrivate: true,
// 注册域名,必填
registryHost: 'registry.cnpm.xx.com',
// 可以 publish package 的用户,必填
admins: {
admin: 'admin'
},
// 同步官方包的模式,必填
syncModel: 'exist', // 'none', 'all', 'exist'
// package 的大小
jsonLimit: 1073741824,
// 不在 cnpm 管理的有私有前缀的 package 的白名单
privatePackages: ['@remobild/react-native-toast']
};
$ vim config/index.js
注释掉 bindingHost,对外网开放,否则只能本机提交
bindingHost: ''
注意 syncModel 不建议写 all, all 模式下会同步整个官方仓库,需要很大的存储空间
确保 logdir, nfsdir, uploadDir 目录权限可写
package 的大小,看自己的包情况,如果有特别大的 package,并且通过 nginx 代理了,那么除了 jsonLimit 外,nginx 的 client_max_body_size 也要修改
<h3>安装依赖:</h3>
```$ npm install --build-from-source --registry=https://registry.npm.taobao.org --disturl=https://npm.taobao.org/mirrors/node
启动:
```# debug 模式
$ npm run dev
后台启动
$ npm start
检查 registry
$ curl http://192.168.33.10:7001
检查 web
$ curl http://192.168.33.10:7002
以上的两个端口也可以通过 config.js 修改,默认的 7001 和 7002 写在 config/index.js 中
<h3>nginx: (<em>这一步非必须,后边 client 直接用 ip 也可以</em>)</h3>
<h4>cnpm.xx.com</h4>
```upstream cnpm {
server 127.0.0.1:7002;
}
server {
listen 80;
server_name cnpm.xx.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://cnpm/;
proxy_redirect off;
}
}
registry.cnpm.xx.com
```upstream registry_cnpm {
server 127.0.0.1:7001;
}
server {
listen 80;
server_name registry.cnpm.xx.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://registry_cnpm/;
proxy_redirect off;
}
}
<p>至此,Server 端的配置就完成了,在本地绑定 host 访问 cnpm.xx.com 就可以看见自己的 npm 仓库了。</p>
<h2>Client</h2>
<p>Client 端主要是配置命令行工具完成注册,登录等步骤后,就可以发布 package 到自己的 npm 仓库中了。</p>
<h3>安装 cnpm:</h3>
```# cnpm 官方有自己的 cnpm 命令,但是在我们的实际使用过程中,发生过一些问题,之后采用了给 npm 官方命令添加别名的方式
$ echo -e '\n#alias for cnpm\nalias cnpm="npm --registry=http://registry.cnpm.xx.com --cache=$HOME/.npm/.cache/cnpm --disturl=http://xx.com --userconfig=$HOME/.cnpmrc"' >> ~/.bashrc && source ~/.bashrc
配置:
```1. 配置 cnpmrc
$ vim ~/.cnpmrc
registry=http://registry.cnpm.xx.com
注册
(注册前需要把要注册的人的邮箱前缀发给管理员, 管理员在上边的 config.js 中添加完毕之后才可以)
$ cnpm adduser
依次输入用户,密码,邮箱登录
$ cnpm login
没有错误表示登录成功
<h3>使用:</h3>
```# publish package
$ mkdir test && cd test
$ cnpm init -y
$ touch test.js
$ cnpm publish
# install package
$ cnpm install @test/test --save
以上是 Client 端的配置过程,还是很简单的。
通过上边的 Server 端和 Client 端的配置,我们就可以在自己公司内发布一些不便公开的 package 到自己的 npm 仓库中。另外,cnpm 也是可以安装官方仓库的 package 的,安装过程中 cnpm 会到自己的仓库中寻找要安装的 package , 找不到的情况下会默认到 https://npm.taobao.org 寻找,这是阿里团队维护的一个完整 https://www.npmjs.com 镜像,同步频率目前为10分钟一次,以保证尽量与官方服务同步。