pomelo源码解析--新建项目(cli工具: pomelo)

2023-05-16

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 -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等命令原理一样,可自行了解下。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

pomelo源码解析--新建项目(cli工具: pomelo) 的相关文章

  • signature=f9281a43abd6807852c6bbdc0be5748c,vue-cli-3-ssr/yarn.lock at master · x007xyz/vue-cli-3-ssr...

    cross spawn 64 5 0 1 cross spawn 64 5 1 0 version 34 5 1 0 34 resolved 34 https registry npmjs org cross spawn cross spa
  • redis cli笔记

    此篇为人个笔记 xff0c 基本是个人常用命令 xff0c 仅供参考 基础操作 redis cli redis span class token number 127 0 span 0 1 637 span class token oper
  • 重装@angular/cli reason: write EPROTO 139955972261696:error:1408F10B:SSL routines:ssl3_get_record:wron...

    前几天不小心卸载了 angular 64 cli 然后重装的时候发现 xff0c 一直报错 如下 xff1a 64 ln622653 npm install g 64 angular cli npm ERR code EPROTO npm
  • Workbox CLI中文版

    在写PWA应用时 xff0c 用到WorkBox工具 xff0c 使用过程中发现没有中文的帮助文档 xff0c 为了体验好一些 xff0c 也为了方便自己和他人查看 xff0c 在这里翻译了一下workbox cli Workbox CLI
  • truffle+ganache-cli构建简单以太坊智能合约并编译部署

    以前接触过以太坊工具链来做区块链练手项目 xff0c 后来荒废了 xff0c 如今再次捡起来 xff0c 算是回忆和加深 之前可能因为网络的原因 xff0c 在truffle各种初始化编译合成智能合约都遇到了好多问题 xff0c 如今再次尝
  • vue-cli 插件开发补充

    官网地址 xff1a https cli vuejs org zh api地址 xff1a https cli vuejs org dev guide plugin api html Plugin API api version 64 vu
  • 机器人地面站-[QGroundControl源码解析]-[2]

    目录 前言 一 QGC 二 QGCComboBox 三 QGCFileDownload 四 QGCLoggingCategory 五 QGCMapPalette 六 QGCPalette 七 QGCQGeoCoordinate 八 QGCT
  • GVINS源码解析

    GVINS是基于VINS MONO写的 xff0c 视觉 IMU部分与VINS MONO类似 xff0c 可参考我的前一篇文章VINS MONO学习 这篇文章主要解析与GNSS有关的部分 持续更新中 文章目录 estimator node
  • 跨域-Vue-Cli配置代理转发

    目标 xff1a 通过配置vue cli请求代理解决开发环境下的跨域问题 vue cli中集成的跨域解决方案 思路 xff1a 在前端服务和后端接口服务之间 架设一个中间代理服务 xff0c 它的地址保持和前端服务一致 xff0c 那么 x
  • Android-Handler源码解析-Message

    成员变量 标识Message public int what 存储简单数据 xff0c 如果存储复杂的数据使用setData 方法 public int arg1 public int arg2 发送给接收者的任意对象 public Obj
  • Vue脚手架(Vue-cli)安装

    脚手架是Vue官方提供的标准化开发工具 开发平台 官方文档开始 vue cli cli c command l line 行 interface 命令行接口工具 第一步 仅第一次执行 全局安装 64 vue cli npm install
  • vue报错: npm run serve报错 ‘vue-cli-service‘ 不是内部或外部命令,也不是可运行的程序

    原因 xff1a 该目录下node modules gt bin gt 没有vue cli service文件 这个时候运行npm run serve 或 npm run dev就会报错 加我weixin xff0c 可帮忙解决 做法一 x
  • Libev源码解析

    最近在看libev源码 xff0c 算是对libev的源码有个比较清晰的了解 总共分3部分来介绍libev 1 Libev是什么 Libev是基于Reactor模式的一个高性能 xff0c 支持高并发的事件库 它本身不仅支持IO xff0c
  • yolov5源码解析--输出

    本文章基于yolov5 6 2版本 主要讲解的是yolov5是怎么在最终的特征图上得出物体边框 置信度 物体分类的 一 总体框架 首先贴出总体框架 xff0c 直接就拿官方文档的图了 xff0c 本文就是接着右侧的那三层输出开始讨论 Bac
  • MSCKF 源码解析 一

    论文 xff1a https arxiv org abs 1712 00036 源码路径 https github com daniilidis group msckf mono 源码框架 上图展示了整个msckf源码框架 xff0c 每当
  • BetaFlight模块设计之三十:Cli模块分析

    BetaFlight模块设计之三十 xff1a Cli模块分析 Cli模块Cli接口Cli框架Cli命令结构主要函数分析cliProcess函数processCharacterInteractive函数processCharacter函数
  • MMdetection的Proposal原理和代码解析

    一 算法原理 接受N级score bbox pred anchor和image shape作为输入 通过anchor和框的偏移 bbox pred 得到proposal 然后对这些proposal做NMS 最后选出前num个 二 执行步骤
  • 使用cobra创建cli命令行工具

    什么是cobra Cobra既是用于创建强大的现代CLI应用程序的库 也是用于生成应用程序和命令文件的程序 Cobra是一个库 提供了一个简单的界面来创建类似于git go工具的强大的现代CLI界面 Cobra也是一个应用程序 它将生成您的
  • 走进 San CLI(上):使用介绍

    本文是 San CLI 的使用和原理的第一篇 主要介绍 San CLI 的初衷和使用 下一篇介绍具体的实现原理 什么是 CLI CLI 是命令行界面 command line interface 的英文缩写 命令行界面是在图形用户界面得到普
  • xxl-job(2.4.1)使用spring-mvc替换netty的功能

    xxl job 2 4 1 使用spring mvc替换netty的功能 1 xxl job core引入spring mvc的依赖

随机推荐