由于 npm 的资源在国外,我们在使用的时候经常遇到网络不稳定导致下载失败的情况,所以我们在开发时一般会使用阿里在国内的镜像资源 =>淘宝 NPM 镜像。 而如果我们想要在公司内部管理我们私有的 npm 包,此时就需要搭建属于我们自己的服务器了。
当前的搭建方式有下面几种:
- Nexus 搭建 npm 私服
- Sinopia 搭建 npm 私服
- cnpm 搭建 npm 私服
本博客基于 cnpmjs.org 搭建,官方 code 地址。
下面我们开始搭建。
cnpmjs.org 项目配置
首先拉取官方项目,我们在本地做个性化定制。
$ git clone https://github.com/cnpm/cnpmjs.org.git
配置文件在 ./config/index.js
中。
几个重要的配置项如下:
webPort: 7002, //展示查询站点访问端口
bindingHost: '127.0.0.1', //监听绑定的 Host,默认127.0.0.1,如果外网访问注释掉即可,不然只能 127.0.0.1 本地访问
// 设置我们的私服服务器 IP 地址,端口保持原有的7001
// registry url name
// 模块注册列表访问域名,装模块时会到这个域名下查找
registryHost: '127.0.0.1:7001',
/**
* 数据库设置
*/
database: {
db: 'cnpmjs', // 数据库名
username: 'root', // 账号
password: '123456', // 密码
// the sql dialect of the database
// - currently supported: 'mysql', 'sqlite', 'postgres', 'mariadb'
dialect: 'mysql', // 根据需要选择使用什么数据库,这里改成 mysql
// custom host; default: 127.0.0.1
host: '127.0.0.1', // 数据库访问IP
// custom port; default: 3306
port: 3306, // 数据库访问端口
// use pooling in order to reduce db connection overload and to increase speed
// currently only for mysql and postgresql (since v1.5.0)
// 缓冲
pool: {
maxConnections: 10,
minConnections: 0,
maxIdleTime: 30000
},
},
// package tarball store in local filesystem by default
// 模块文件存储位置,默认将发布的私有模块跟缓存公共模块存储在本地文件系统中,路径~/.cnpmjs.org/nfs
nfs: require('fs-cnpm')({
dir: path.join(dataDir, 'nfs')
}),
// 管理员帐号
// name 表示用户名和密码,value 值是邮箱,可以设置添加多个
admins: {
// name: email
fengmk2: 'fengmk2@gmail.com',
admin: 'admin@cnpmjs.org',
dead_horse: 'dead_horse@qq.com',
wenjw: 'wenjw@test.com'
}
// 是否允许所有人发布,true表示只有管理员才能发布,其他用户可以同步。false表示任何人
// 不管是 true 和 false 项目还是必须带有私有标示
enablePrivate: false,
// 我们私有包的前缀,带有以下前缀的包才支持操作
scopes: [ '@58', '@lw-test' ]
// 私有模块非 scopes 白名单,各种非以 scope 方式发布的老模块的白名单管理,数组形式维护
privatePackages: [],
// npm 官方 registry 地址,不会直接从这个地址同步模块,但有时会从这里获取模块信息,除非必要请勿更改
officialNpmRegistry: 'https://registry.npmjs.com',
officialNpmReplicate: 'https://replicate.npmjs.com',
//同步模块上游registry地址
sourceNpmRegistry: 'https://registry.npm.taobao.org',
//上游 registry 是否是 cnpm,默认 true
// 如果使用 npm 官方地址作为同步上游,请设置为 false
sourceNpmRegistryIsCNpm: true,
//若安装时模块不存在,是否向源 registry 进行同步,默认true
syncByInstall: true,
// 同步模式选项
// none: 不进行同步,只管理用户上传的私有模块,公共模块直接从上游获取
// exist: 只同步已经存在于数据库的模块
// all: 定时同步所有源 registry 的模块
syncModel: 'exist', // 'none', 'all', 'exist'
// 同步时间间隔,10 分钟
syncInterval: '10m',
// 是否同步模块中 devDependencies,默认 false
syncDevDependencies: false,
// https://github.com/cnpm/cnpmjs.org/issues/1149
// if enable this option, must create module_abbreviated and package_readme table in database
enableAbbreviatedMetadata: true,
我们可以先启动看一下效果,执行下面命令
$ node dispatch.js
这里输入 ip 地址和端口就可以看到界面了。
MySql 数据库配置
然后我们执行相关命令更改数据库。
$ mysql -uroot -p123456
创建我们需要的数据库
mysql> create database cnpmjs;
切换数据库
mysql> use cnpmjs;
倒入表,位置在我们拉取项目的 docs/db.sql
mysql> source cnpmjs.org/docs/db.sql;
查看导入的表
mysql> show tables;
私有库使用
因为发布时需要设置私有 registry ,我们安装 nrm
来管理。
$ node i -g nrm
添加私有库的源,并切换
$ nrm add cnpmorg 'http://127.0.0.1:7001/'
$ nrm use cnpmorg
$ nrm ls
此时可以看到我们的源已经切换
登录
$ npm login
然后我们随便创建一个小项目发布测试一下。测试目录下我们执行发布命令。
$ npm publish
在 http://127.0.0.1:7002/
下,可以搜索到我们刚发布的包。
命令行查看
$ npm view @58/test1
然后执行安装操作,可以看到安装成功
$ npm i @58/test1
再测试一下安装公共包
$ npm i react
到这里我们的私服就搭建完成了。
总结
最后总结一下遇到的问题
- 首先是 mysql 初始化的时候密码没有记住,导致没有登录密码。如下解决方案
注意:进入mysql时,有时候会因为忘记密码导致进入失败,解决方法是重置密码。
- 在系统设置方法中,或在终端通过命令关闭mysql服务
- 在终端使用命令
sudo /usr/local/mysql/bin/mysqld_safe --skip-grant-tables &
,以安全模式启动mysql服务。 - 打开另一个终端
- 在终端执行命令
sudo /usr/local/mysql/bin/mysql -u root
(此时要求输入的密码为用户开机密码), 进入 mysql 后输入命令flush privileges;
,注意 sql 命令;
是必须的。 - 修改密码,
set password for 'root'@'localhost' = password('123456');
- 修改完成后,即可以用新密码通过命令
mysql -u root -p123456
进入mysql。
- npm install 命令报错,404。如下图。
这里注意,registryHost: ‘127.0.0.1:7001’,一定要配置自己的服务器 IP ,而不能用默认的配置。