基于CNPM的本地私有库搭建

原因

NPM(Node Package Manager)是一个Nodejs的包管理和分发工具。同时其本身也是一家商业公司。近期发生了一起Left-Pad事件,leftPad这个方法本身其实实现起来非常简单,就短短几行代码,当然考虑到性能最优要写好一个简单的工具方法并不是那么容易的。由于某些原因,导致leftPad这个npm的作者愤怒地unpublish了自己在npm上的所有包,而这个基础包恰恰被很多其他npm依赖着,直接就导致了BabelReactNativeEmber等大量工具构建失败,影响十分重大,这必然引起了广大Nodejs开发者的信心。开始质疑这种第三方包的管理方式,比如有人恶意地植入一些垃圾代码等等。

因此,企业内部一般采取搭建本地私有库来维护和管理所用到的依赖库,我们可以直接改造别人的放在内部供自己使用,也不用担心别人会unpublish的他们库导致自己的项目找不到依赖。

CNPM的私有库搭建

这里主要采用的是基于cnpm的搭建方式。它允许定时同步手动同步公共NPM,也可以自己publish私有的NPM。

准备工作

操作系统: OSX
数据库: MySQL
NodeJS: 4.4.0

安装部署

下载工程
$ git clone git://github.com/fengmk2/cnpmjs.org.git
$ cd cnpmjs.org
创建表
$ mysql -u root -p
mysql> create database cnpmjs;
mysql> use cnpmjs;
mysql> source docs/db.sql
启动配置

编写配置文件config/config.js

module.exports = {
    debug: false,
    enableCluster: true, // enable cluster mode
    mysqlServers: [
      {
        host: 'localhost',
        port: 3306,
        user: 'cnpmjs',
        password: 'cnpmjs123',
      }
    ],
    mysqlDatabase: 'cnpmjstest',
    redis: {
      host: 'localhost',
      port: 6379,
    },
    nfs: null, //use your own CND here
    enablePrivate: true, // enable private mode, only admin can publish, other use just can sync package from source npm
    admins: {
      admin: 'admin@cnpmjs.org',
    },
    syncModel: 'exist'
  };

注意: nfs指的是同步的modules的存储路径,可以支持与OSS或者七牛的集成,具体可参考文档,如果采用本地存储,就删除nfs: null 这一行,本地存储在~/.cnpmjs.org/nfs目录下。

启动服务器

安装依赖

$ make install

启动

$ npm run start

看到

Starting cnpmjs.org ...
Start nodejs success. PID=42421

就成功了。

然后可以访问http://localhost:7002进行验证。

关闭

$ npm run stop
客户端安装
$ npm install cnpm -g

编辑~/.cnpmrc文件

registry=http://127.0.0.1:7001

接下来,在客户端安装包依赖的时候,使用cnpm install xxx,就可以从自己部署的私有库进行安装,如果私有库中不存在,根据默认配置的源站进行获取并同步到私有库中,具体可以参考工程下的config/index.js里的其他配置。

发布私有包

CNPM默认规定,只有admin才可以进行发布。

登录admin

$ cnpm login

如下图:

创建测试npm

$ mkdir fx-test-npm
$ cd fx-test-npm
$ cnpm init

注意: publish的npm必须在自己的scopes下,默认的scopes是[ '@cnpm', '@cnpmtest', '@cnpm-test'],可以在config/config.js下添加scopes: ['@fx']将其修改为我们自己定义的。

因此,我们在配置package.json的时候,将其name设置为@fx/fx-test-npm

发布

$ cd fx-test-npm
$ cnpm publish .

如下图:

还可以去存储的地方验证下:

最后,我们就可以这样去使用私有模块

require('@fx/fx-test-npm')