pomelo怎么新建项目

官方文档
1. 安装pomelo
2. 新建项目HelloWorld
我简单整理了下创建新项目关键步骤:

  1. 安装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

  1. 新建项目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 -rvar 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 websocketvar 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.iovar 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 wssvar 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 wssvar 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 wssvar 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.iovar 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)相关推荐

  1. 【源码解析】压测工具vegeta

    序言 github地址:https://github.com/tsenart/vegeta 第一次写源码解析的博客,就拿自己最熟悉的压测工具vegeta(贝吉塔)来介绍.本篇文章只介绍vegeta的l ...

  2. elementUi源码解析(1)--项目结构篇

    因为在忙其他事情好久没有更新iview的源码,也是因为后面的一些组件有点复杂在考虑用什么方式把复杂的功能逻辑简单的展示出来,还没想到方法,突然想到element的组件基本也差不多,内部功能的逻辑也差不 ...

  3. h2o.ai源码解析(1)—项目简介

    h2o.ai项目简介 参考h2o.ai官网中给出的项目定位是"open source platform for AI".相较于当前市面上的机器学习平台,h2o.ai的优势在于: - ...

  4. .NET Core实战项目之CMS 第三章 入门篇-源码解析配置文件及依赖注入

    写在前面 上篇文章我给大家讲解了ASP.NET Core的概念及为什么使用它,接着带着你一步一步的配置了.NET Core的开发环境并创建了一个ASP.NET Core的mvc项目,同时又通过一个实战 ...

  5. 美团动态线程池实践思路开源项目(DynamicTp),线程池源码解析及通知告警篇

    大家好,这篇文章我们来聊下动态线程池开源项目(DynamicTp)的通知告警模块.目前项目提供以下通知告警功能,每一个通知项都可以独立配置是否开启.告警阈值.告警间隔时间.平台等,具体代码请看core ...

  6. Android Hawk数据库的源码解析,Github开源项目,基于SharedPreferences的的存储框架

    今天看了朋友一个项目用到了Hawk,然后写了这边文章 一.了解一下概念 Android Hawk数据库github开源项目 Hawk是一个非常便捷的数据库.操作数据库只需一行代码,能存任何数据类型. ...

  7. 轻触开源(三)-Gson项目源码解析_贰

    2019独角兽企业重金招聘Python工程师标准>>> 转载请注明出处:https://my.oschina.net/u/874727/blog/750473 Q:102525062 ...

  8. 免Root 实现App加载Xposed插件的工具Xpatch源码解析(一)

    前言 Xpatch是一款免Root实现App加载Xposed插件的工具,可以非常方便地实现App的逆向破解(再也不用改smali代码了),源码也已经上传到Github上,欢迎各位Fork and St ...

  9. 【开源项目】动态线程池框架Hippo4j源码解析

    动态线程池框架Hippo4j源码解析 项目简介 Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池等功能,为业务系统提高线上运行保障能力. 快速开始 https://hippo4 ...

最新文章

  1. 用XML反序列化快速完成ASP.NET配置文件
  2. 二叉树的前序、中序和后序遍历介绍及案例
  3. agx 安装ros opencv_怎样在ROS下实现基于YOLO的px4无人机目标检测?
  4. linux 进程的vss rss uss,内核/内存管理中的VSS/RSS/PSS/USS
  5. Python运算符优先级
  6. matlab连续型随机变量,matlab连续型随机变量的分布.doc
  7. shell 中的参数替换
  8. 阿里云服务器好吗?老司机谈谈阿里云服务器的使用感受
  9. 电子(自旋、轨道、耦合)磁矩
  10. 梦幻显示器,国产屏幕OLED崛起
  11. 宣州谢朓楼饯别校书叔云
  12. 国元证券 即将产生,借壳
  13. IDEA常用快捷键(四)--查找文件、查找类
  14. 2015物联网安全年报
  15. 辉太郎看前端(js异步宏任务和微任务)
  16. 大炮评级:玩你只是寂寞,玩死你才是目的,我可是币圈墓地!
  17. 区块链发展面临三大挑战
  18. 吐血推荐 | 珍藏多年的 Chrome 插件,务必收藏
  19. 电赛设计报告模板及历年资源
  20. 【AI绘图学习笔记】深度前馈网络(二)

热门文章

  1. 成功率100%的通达信指标公式,你敢相信吗?
  2. Pip 安装,卸载,更新安装包
  3. 在iPad应用中嵌入字体的方法——非人云亦云版
  4. 百度指数专业版相关指标含义
  5. 3.笔记go语言——函数
  6. 【python】使用喵码实现警报微信提醒,提供代码和详细注释
  7. Java打包后运行jar包报错Caused by: org.springframework.beans.factory.BeanCreationException: Error creating be
  8. java 虚拟机设置 Xms Xmx PermSize MaxPermSize
  9. 如何将知网下载的caj文件转换为pdf文件
  10. XSS(跨站脚本攻击)原理详解(内含攻击实例)