pomelo源码解析--新建项目(cli工具: pomelo)
Posted 夜色魅影
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pomelo源码解析--新建项目(cli工具: pomelo)相关的知识,希望对你有一定的参考价值。
pomelo怎么新建项目
官方文档
1. 安装pomelo
2. 新建项目HelloWorld
我简单整理了下创建新项目关键步骤:
- 安装pomelo
方式一:
$ npm install pomelo -g
·
方式二:
$ git clone https://github.com/NetEase/pomelo.git
$ cd pomelo
$ npm install -g
·
注:如果npm安装特别慢,安装国内淘宝镜像cnpm,此后的命令我们可以用cnpm 来替代 npm。安装命令如下:
npm install -g cnpm --registry=https://registry.npm.taobao.org
- 新建项目HelloWorld
$ mkdir HelloWorld
$ cd HelloWorld
$ pomelo init
按照这些执行完我们最终成功创建了一个名叫HelloWorld的新项目:
npm下载安装、发布
为什么执行npm install pomelo -g就可以安装pomelo模块?为什么简单执行pomelo init就可以新建一个项目了? 这些命令怎么来的?内部做了什么操作?
要搞清这些疑问之前,我们要先了解下nodejs如何编写、发布cli命令行工具
参考:https://blog.csdn.net/weixin_43254265/article/details/84797130
了解完npm怎么发布、安装包后,下面我们来分析下pomelo init源码实现流程:
首先我们可以看到pomelo源码中package.json配置中bin键
"bin": {
"pomelo": "./bin/pomelo"
},
执行pomelo实际运行的是/bin/pomelo,然后看下里面的pomelo init命令
// program = require('commander');
program.command('init [path]')
.description('create a new application')
.action(function(path) {
init(path || CUR_DIR);
});
最后执行的init函数
function init(path) {
console.log(INIT_PROJ_NOTICE);
connectorType(function(type) { // 交互式命令(可用inquirer),用户输入选择客户端使用的协议连接组件,然后回调返回
emptyDirectory(path, function(empty) { // 判断path目录是否为空目录,默认命令执行的当前目录
if(empty) {
process.stdin.destroy();
createApplicationAt(path, type); // 这里创建项目了,做了一系列复制、删除、替换操作
} else {
confirm('Destination is not empty, continue? (y/n) [no] ', function(force) {
process.stdin.destroy();
if(force) {
createApplicationAt(path, type);
} else {
abort('Fail to init a project'.red);
}
});
}
});
});
}
/**
* Create directory and files at the given directory `path`.
*
* @param {String} ph
*/
function createApplicationAt(ph, type) {
var name = path.basename(path.resolve(CUR_DIR, ph));
copy(path.join(__dirname, '../template/'), ph);
mkdir(path.join(ph, 'game-server/logs'));
mkdir(path.join(ph, 'shared'));
// rmdir -r
var rmdir = function(dir) {
var list = fs.readdirSync(dir);
for(var i = 0; i < list.length; i++) {
var filename = path.join(dir, list[i]);
var stat = fs.statSync(filename);
if(filename === "." || filename === "..") {
} else if(stat.isDirectory()) {
rmdir(filename);
} else {
fs.unlinkSync(filename);
}
}
fs.rmdirSync(dir);
};
setTimeout(function() {
switch(type) {
case '1':
// use websocket
var unlinkFiles = ['game-server/app.js.sio',
'game-server/app.js.wss',
'game-server/app.js.mqtt',
'game-server/app.js.sio.wss',
'game-server/app.js.udp',
'web-server/app.js.https',
'web-server/public/index.html.sio',
'web-server/public/js/lib/pomeloclient.js',
'web-server/public/js/lib/pomeloclient.js.wss',
'web-server/public/js/lib/build/build.js.wss',
'web-server/public/js/lib/socket.io.js'];
for(var i = 0; i < unlinkFiles.length; ++i) {
fs.unlinkSync(path.resolve(ph, unlinkFiles[i]));
}
break;
case '2':
// use socket.io
var unlinkFiles = ['game-server/app.js',
'game-server/app.js.wss',
'game-server/app.js.udp',
'game-server/app.js.mqtt',
'game-server/app.js.sio.wss',
'web-server/app.js.https',
'web-server/public/index.html',
'web-server/public/js/lib/component.json',
'web-server/public/js/lib/pomeloclient.js.wss'];
for(var i = 0; i < unlinkFiles.length; ++i) {
fs.unlinkSync(path.resolve(ph, unlinkFiles[i]));
}
fs.renameSync(path.resolve(ph, 'game-server/app.js.sio'), path.resolve(ph, 'game-server/app.js'));
fs.renameSync(path.resolve(ph, 'web-server/public/index.html.sio'), path.resolve(ph, 'web-server/public/index.html'));
rmdir(path.resolve(ph, 'web-server/public/js/lib/build'));
rmdir(path.resolve(ph, 'web-server/public/js/lib/local'));
break;
case '3':
// use websocket wss
var unlinkFiles = ['game-server/app.js.sio',
'game-server/app.js',
'game-server/app.js.udp',
'game-server/app.js.sio.wss',
'game-server/app.js.mqtt',
'web-server/app.js',
'web-server/public/index.html.sio',
'web-server/public/js/lib/pomeloclient.js',
'web-server/public/js/lib/pomeloclient.js.wss',
'web-server/public/js/lib/build/build.js',
'web-server/public/js/lib/socket.io.js'];
for(var i = 0; i < unlinkFiles.length; ++i) {
fs.unlinkSync(path.resolve(ph, unlinkFiles[i]));
}
fs.renameSync(path.resolve(ph, 'game-server/app.js.wss'), path.resolve(ph, 'game-server/app.js'));
fs.renameSync(path.resolve(ph, 'web-server/app.js.https'), path.resolve(ph, 'web-server/app.js'));
fs.renameSync(path.resolve(ph, 'web-server/public/js/lib/build/build.js.wss'), path.resolve(ph, 'web-server/public/js/lib/build/build.js'));
break;
case '4':
// use socket.io wss
var unlinkFiles = ['game-server/app.js.sio',
'game-server/app.js',
'game-server/app.js.udp',
'game-server/app.js.wss',
'game-server/app.js.mqtt',
'web-server/app.js',
'web-server/public/index.html',
'web-server/public/js/lib/pomeloclient.js'];
for(var i = 0; i < unlinkFiles.length; ++i) {
fs.unlinkSync(path.resolve(ph, unlinkFiles[i]));
}
fs.renameSync(path.resolve(ph, 'game-server/app.js.sio.wss'), path.resolve(ph, 'game-server/app.js'));
fs.renameSync(path.resolve(ph, 'web-server/app.js.https'), path.resolve(ph, 'web-server/app.js'));
fs.renameSync(path.resolve(ph, 'web-server/public/index.html.sio'), path.resolve(ph, 'web-server/public/index.html'));
fs.renameSync(path.resolve(ph, 'web-server/public/js/lib/pomeloclient.js.wss'), path.resolve(ph, 'web-server/public/js/lib/pomeloclient.js'));
rmdir(path.resolve(ph, 'web-server/public/js/lib/build'));
rmdir(path.resolve(ph, 'web-server/public/js/lib/local'));
fs.unlinkSync(path.resolve(ph, 'web-server/public/js/lib/component.json'));
break;
case '5':
// use socket.io wss
var unlinkFiles = ['game-server/app.js.sio',
'game-server/app.js',
'game-server/app.js.wss',
'game-server/app.js.mqtt',
'game-server/app.js.sio.wss',
'web-server/app.js.https',
'web-server/public/index.html',
'web-server/public/js/lib/component.json',
'web-server/public/js/lib/pomeloclient.js.wss'];
for(var i = 0; i < unlinkFiles.length; ++i) {
fs.unlinkSync(path.resolve(ph, unlinkFiles[i]));
}
fs.renameSync(path.resolve(ph, 'game-server/app.js.udp'), path.resolve(ph, 'game-server/app.js'));
rmdir(path.resolve(ph, 'web-server/public/js/lib/build'));
rmdir(path.resolve(ph, 'web-server/public/js/lib/local'));
break;
case '6':
// use socket.io
var unlinkFiles = ['game-server/app.js',
'game-server/app.js.wss',
'game-server/app.js.udp',
'game-server/app.js.sio',
'game-server/app.js.sio.wss',
'web-server/app.js.https',
'web-server/public/index.html',
'web-server/public/js/lib/component.json',
'web-server/public/js/lib/pomeloclient.js.wss'];
for(var i = 0; i < unlinkFiles.length; ++i) {
fs.unlinkSync(path.resolve(ph, unlinkFiles[i]));
}
fs.renameSync(path.resolve(ph, 'game-server/app.js.mqtt'), path.resolve(ph, 'game-server/app.js'));
fs.renameSync(path.resolve(ph, 'web-server/public/index.html.sio'), path.resolve(ph, 'web-server/public/index.html'));
rmdir(path.resolve(ph, 'web-server/public/js/lib/build'));
rmdir(path.resolve(ph, 'web-server/public/js/lib/local'));
break;
}
var replaceFiles = ['game-server/app.js',
'game-server/package.json',
'web-server/package.json'];
for(var j = 0; j < replaceFiles.length; j++) {
var str = fs.readFileSync(path.resolve(ph, replaceFiles[j])).toString();
fs.writeFileSync(path.resolve(ph, replaceFiles[j]), str.replace('$', name));
}
var f = path.resolve(ph, 'game-server/package.json');
var content = fs.readFileSync(f).toString();
fs.writeFileSync(f, content.replace('#', version));
}, TIME_INIT);
}
这样就生成了我们上面截图的HelloWorld项目了!至于其它pomelo stop、list、add、kill、restart、masterha等命令原理一样,可自行了解下。
以上是关于pomelo源码解析--新建项目(cli工具: pomelo)的主要内容,如果未能解决你的问题,请参考以下文章
pomelo源码解析--新建项目(cli工具: pomelo)
pomelo源码解析--新建项目(cli工具: pomelo)