zoukankan      html  css  js  c++  java
  • 【Skylor CLI】从零开始打造属于自己的超级命令行工具(一)编写一个简单的cli

    经历过多次的从0到1,手动搭建了N个项目之后,大量的重复性劳动使我疲惫。
     
    是不是可以把这些重复性劳动记录下来,下次一句命令就可以直接生成。
     
    正是这个“懒”,使得我有了打造属于自己的超级命令行工具的想法…^o^,也是这个工具的最伟大目标所在。
     
    项目地址:github / npm 搜:skylor-cli
     
    开始设计
    • api - NodeApi -> 接口服务
    • io - Socket -> 长链接服务
    • mi - Micro -> 微服务架构
    • ra - ReactAdmin -> React搭建后台管理应用
    • r - React -> React搭建web应用
    • v - Vue -> Vue搭建web应用
    • rn - ReactNative -> RN搭建移动端应用
    • re - React Electron -> 桌面应用

    效果图

    skylor-cli 工具预览图

    主要源代码

      1 #!/usr/bin/env node
      2 
      3 const program = require('commander');
      4 const shell = require('shelljs');
      5 const chalk = require('chalk');
      6 const inquirer = require('inquirer');
      7 const clone = require('./lib/clone');
      8 const pkg = require('./package');
      9 
     10 program
     11   .version(pkg.version)
     12   .description(pkg.dependencies)
     13 
     14 program
     15   .command('init')
     16   .alias('i')
     17   .description('请选择模版初始化工程')
     18   .action(function() {
     19     require('figlet')('S K Y L O R', function(err, data) {
     20       if (data) {
     21         console.log(chalk.red(data))
     22       }
     23 
     24       console.log('目前skylor-cli支持以下模板:');
     25       listTemplateToConsole();
     26 
     27       const prompt = inquirer.createPromptModule();
     28       prompt({
     29         type: 'list',
     30         name: 'type',
     31         message: '项目类型:',
     32         default: 'r   - React 最佳实践',
     33         choices: [
     34           'api - Api 服务器工程',
     35           'io  - Socket 服务器工程',
     36           'mi  - Node.js 微服务器工程',
     37           'r   - React 最佳实践',
     38           'ra  - React 后台管理最佳实践',
     39           'rn  - React Native 最佳实践',
     40           'v   - Vue 最佳实践',
     41         ],
     42       }).then((res) => {
     43         const type = res.type.split(' ')[0];
     44         prompt({
     45           type: 'input',
     46           name: 'project',
     47           message: '项目名称:',
     48           validate: function (input) {
     49             // Declare function as asynchronous, and save the done callback
     50             const done = this.async();
     51             // Do async stuff
     52             setTimeout(function() {
     53               if (!input) {
     54                 // Pass the return value in the done callback
     55                 done('You need to provide a dirName.');
     56                 return;
     57               }
     58               // Pass the return value in the done callback
     59               done(null, true);
     60             }, 0);
     61           }
     62         }).then((iRes) => {
     63           const project = iRes.project;
     64           let pwd = shell.pwd();
     65           clone(`https://github.com/skyFi/skylor-${type}.git`, pwd + `/${project}`, {
     66             success() {
     67               // 删除 git 目录
     68               shell.rm('-rf', pwd + `/${project}/.git`);
     69 
     70               // 提示信息
     71               console.log(`项目地址:${pwd}/${project}/`);
     72               console.log('接下来你可以:');
     73               console.log('');
     74               console.log(chalk.blue(`    $ cd ${project}`));
     75               console.log(chalk.blue(`    $ npm install`));
     76               console.log(chalk.blue(`    $ npm start`));
     77               console.log('');
     78             },
     79             fail(err) {
     80               console.log(chalk.red(`${err}`));
     81             },
     82             onData(data = '') {
     83               const d = data.toString();
     84               if (d.indexOf('fatal') !== -1 || d.indexOf('error') !== -1) {
     85                 console.log(chalk.red(`${data}`));
     86               } else {
     87                 console.log(chalk.blue(`${data}`));
     88               }
     89             },
     90           })
     91         });
     92       });
     93     });
     94   }).on('--help', function() {
     95   console.log('');
     96   console.log('Examples:');
     97   console.log('');
     98   console.log(chalk.blue('  $ skylor i'));
     99   console.log(chalk.blue('  $ skylor init'));
    100   console.log('');
    101   console.log('All Available Templates:');
    102   listTemplateToConsole();
    103 });
    104 
    105 program.parse(process.argv);
    106 
    107 function listTemplateToConsole() {
    108   console.log('');
    109   console.log(chalk.green('  api  -  Api 服务器工程'));
    110   console.log(chalk.green('  io   -  Socket 服务器工程'));
    111   console.log(chalk.green('  mi   -  Nodejs 微服务器工程'));
    112   console.log(chalk.green('  r    -  React 最佳实践'));
    113   console.log(chalk.green('  ra   -  React 后台管理最佳实践'));
    114   console.log(chalk.green('  rn   -  React Native 最佳实践'));
    115   console.log(chalk.green('  v    -  Vue 最佳实践'));
    116   console.log('');
    117 }
    源码(index.js)
  • 相关阅读:
    安装pykeyboard模块
    Windows Defender Antivirus Service经常性出现占用CPU厉害
    Xpath 语法笔记
    通过docker部署rocketmq双主双从集群
    解决提取Mybatis多数据源公共组件“At least one base package must be specified”的问题
    设计模式-单例模式
    通过阳历生日计算星座,阴历生日,生辰八字,生肖五行
    设计模式-抽象工厂模式
    设计模式-工厂方法模式
    常用的MD5工具类
  • 原文地址:https://www.cnblogs.com/skylor/p/9662550.html
Copyright © 2011-2022 走看看