一统江湖的大前端(6)commander.js + inquirer.js——懒,才是第一辈子产力

《一统江湖的大前端》系列是本身的前端学习笔记,旨在介绍javascript在非网页开发领域的应用案例和发现各种好玩的js库,不按期更新。若是你对前端的理解仍是写写页面绑绑事件,那你真的是有点OUT了,前端能作的事情已经太多了, 手机app开发 , 桌面应用开发 , 用于神经网络人工智能的库 , 页面游戏 , 数据可视化 , 甚至 嵌入式开发 ,什么火就搞什么,活脱脱一个蹭热点小能手。若是你也以为前端的平常开发有些枯燥,不妨一块儿来看看前端的另外一番模样。javascript


一.[懒]——才是第一辈子产力

你没有看错,绝壁是第一辈子产力,技术的进步,不少时候都是由于一些很是聪明的人难以忍受一些(在他们眼里)枯燥重复且低效的东西,从而发明出的东西,不管这些新发明在经历了迭代和打磨以后看起来多么牛逼耀眼,但其本质基本均可以概括为:html

是聪明的人搞出的可让本身更省事的东西。前端

  • jQuery的流行,是由于开发者懒得为DOM编写跨浏览器兼容性代码
  • Angular.js的流行, 是由于开发者连DOM都懒得操做
  • Bootstrap的流行, 是由于开发者懒得编写自适应样式
  • Webpack的流行, 是由于开发者懒得作一系列上线前的准备工做
    ......

有的人越懒越牛逼,有的人越懒越逗逼,看来懒也是个技术活,懒出高度,懒出艺术,那才是真的高端懒。vue

二.从GUI到CLI

GUI(Grapic User Interface,即图形化用户界面)和CLI(Command Line Interface,即命令行交互界面)都有其拥护者。
你们都懒,只是对懒的认知不一样,用GUI的人懒得去记命令,用CLI的人懒得去挪鼠标。java

不少前端童鞋都经过可视化工具小乌龟来管理git代码仓库,可视化工具的好处在于可让初学者能够更直观更容易地去管理代码。

可是笔者发现不少熟练的开发者都更喜欢使用命令行工具(如下简称Cli工具),不只由于Cli工具能够知足装X需求,更是由于它能够帮你省掉不少繁琐的移动鼠标和点击的动做。
有时候你并不须要去记忆不少指令和参数(固然用的次数多了,你不想记也记住了),几乎全部的命令行工具只要简单滴使用-h--help参数就能够打印出帮助文件,你彻底能够边学边用,逐步熟悉。node

不少熟悉Vue的同窗都使用过vue-cli命令行工具来初始化一个Vue项目,以下图所示,经过向导式问答收集关键参数信息,而后自动生成相应的工程文件,比你本身各类新建文件和新建文件夹效率高多了。
git

接下来,请跟随笔者一块儿,看看一个前端开发人员如何从零开始打造一款属于本身的cli工具吧~github

三.相关知识储备

1.前提条件
你须要一些Node.js的API知识和一些基本的命令行使用经验。详细的文档能够访问NodeJs官方API获取更多信息。web

2.readline
readline工具包用于逐行处理信息,经常使用的API包括:vue-cli

  • createInterface
    用于建立接口实例,成功调用后返回一个接口实例,调用后使用方法以下:
var rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});
  • rl.question(query, callback)
    实例方法,提供一个问答式单行交互方法,向用户展现提示信息,而后接受并处理用户输入,调用方法以下:
rl.question('你学会怎么用了吗?',function(input){
      console.log('你输入了:',input);
  })
  • rl.write(info)
    实例方法,向建立rl接口实例时链接的output输出流输出信息,一般使用主进程输出流process.stdout,调用方法以下:
rl.write('我是这样用的');

作个Demo轻松一下(demo的源码请在附件拿):

3.child_process
child_process包提供了利用子进程执行命令或调用文件的能力,经常使用的API包括:

  • child_process.spawn()
    实际执行方法,其余方法均为基于此方法的封装,使用方式以下:
const { spawn } = require('child_process');
    const ls = spawn('ls', ['-lh', '/usr']);

    ls.stdout.on('data', (data) => {
      console.log(`stdout: ${data}`);
    });

    ls.stderr.on('data', (data) => {
      console.log(`stderr: ${data}`);
    });

    ls.on('close', (code) => {
      console.log(`child process exited with code ${code}`);
    });
  • child_process.exec(), child_process.execFile()及同名的同步方法
    均是对spawn方法必定程度上的封装,使用更方便。

再来个Demo轻松一下,经过在windows命令行工具中执行js文件,执行了dir命令(demo的源码请在附件拿):

ps:乱码的问题涉及到子进程和主进程通信时的信息的编码和解码问题,遇到实际问题的童鞋能够了解一下iconv-lite这个插件.

四.guide风格命令行开发工具——inquirer.js

github地址为:Inquirer.js地址
guide风格的命令行,指提问-回答模式的命令行,inquirer.js支持常见的input输入,单选,多选,是/否等常见提问类型,并暴露了增长自定义类型的接口,参考官方文档很容易使用。

API使用举例:

const questions = [];

  inquirer
  .prompt(
      /* Pass your questions in here */
      [{
        type: 'confirm',
        name: 'toBeDelivered',
        message: 'Is this for delivery?',
        default: false
      }]
  )
  .then(answers => {
     // Use user feedback for... whatever!!
  });

来看看官方提供的一个Pizza订购工具pizza.js的效果(是否是有vue-cli的既视感~~~):

五.git风格命令行开发工具——commander.js

github地址为:Commander.js地址
git风格命令行,是指经过主指令+子指令+参数的模式运行命令实现功能,和guide风格命令行没有本质区别,只是使用习惯的偏好。
API使用举例:

program
  .version('0.0.1')
  .description('An application for pizzas ordering')
  .option('-p, --peppers', 'Add peppers')
  .option('-P, --pineapple', 'Add pineapple')
  .option('-b, --bbq', 'Add bbq sauce')
  .option('-c, --cheese <type>', 'Add the specified type of cheese [marble]')
  .option('-C, --no-cheese', 'You do not want any cheese')
  .parse(process.argv);

来看看官方提供的这个Pizza订购工具pizza.js的效果(老外是有多喜欢吃Pizza!!!):

六.不一样风格的实现思路

1.基本架构

  • web版本
    • 前端使用任意框架制做,点击某功能按钮时,向后端发送带参请求
    • 后端为node服务器,监听指定端口,接收到客户端请求后,调用具体功能
    • 根据后端执行状况信息在前端展现的实时性要求,选择长链接或普通链接
    • 后端使用child_process或相关类库实现命令并将信息传输至前端
  • Guide风格命令行
    • 直接使用inquirer.js库编写问题组或分支问题树
    • inquirer.js最终将用户输入绑定在一个对象上
    • 使用inquirer.js收集到的参数
    • 带参数运行命令或脚本
  • git风格命令行
    • 直接使用commander.js库的API编写支持的指令
    • commander.js会从注册的命令及子命令中寻找匹配
    • 使用commander.js收集到的参数运行对应的命令或脚本

2.其余问题

  • 兼容性
    • 使用多种脚本格式
      为了兼容不一样运行环境,能够为实际须要执行的命令准备.bat.sh两套脚本,在node.js代码中根据process.platform查询当前系统环境并调用对应格式的脚本
    • 使用兼容性插件库
      例如《一统江湖的大前端(4)——Shell.js》中说起的shell.js库,可将自动化脚本重构为js版本代码,实现跨平台运行。
  • 全局执行命令
    • 开发版本
      开发版本的程序,能够在代码根目录中使用npm link将其注册为全局安装,当开发完毕正式发布后,使用npm unlink去除链接便可。
    • 发布版本
      当node包开发完成并使用publish命令正式发布之后,便可经过npm install -g XXXyarn global add XXX直接从npm上下载并全局安装,而后便可全局使用。

七.要什么demo?直接搞实战!

接下来咱们在Windows环境下实现一个自动化脚本,实现的功能主要包括:

  • 1.删除旧目录
  • 2.新建目录
  • 3.从远程git仓库指定分支下载代码
  • 4.在本地创建新分支并

auto_download.js源码:

var child_process = require('child_process');
function execTask(issueNumber, openLocalhost) {
    //示例中的自定义配置信息从configJson对象中获取
    var originDir = configJson['项目信息']['远程仓库地址'];
    var originBranch = configJson['feature分支']['远程分支名称'];
    var destDir = configJson['项目信息']['本地仓库地址'];
    var projectName = configJson['项目信息']['项目名称'] + '_issue';
    var devBranch = configJson['本地开发']['默认分支前缀'] + issueNumber;

    //执行下载脚本
    var issue_process = child_process.spawn('download_dev_branch.bat',
        [destDir, projectName, originDir, originBranch, devBranch],
        {
            stdio : 'inherit'
        });

        //监听标准输出
        issue_process.stdout
        .on('exit', function (number) {
            console.log(number);
            console.log('感谢您使用Dash-Toolbox!')
        });
}

execTask(12315, true);

自动化脚本download_dev_branch.bat源码:

@echo off
rem 当前脚本用于将远程仓库的开发分支代码下载至指定的本地目录并生成开发分支
rem %1 - 本地仓库文件夹
rem %2 - 本地指定分支文件夹名
rem %3 - 远程仓库地址
rem %4 - 远程开发分支名
rem %5 - 包含issue代码的本地分支
@echo on
cd %1 
rmdir /s/q %2
mkdir %2 && cd %2
git init
git remote add origin %3
git fetch origin %4 :%5 --progress --no-tags
git checkout %5
exit(0)

使用方法:
在文件目录下开启命令行cmd.exe,输入node auto_download便可看到在对应的目录下载了代码:

自动化脚本的部分也能够采用nodeFile API来实现。

八.后记

在学习了以上知识后,笔者决定开发一款命令行工具——Dash-Toolbox
其目的主要是:
在保密性要求较高因此不通外网的环境下,将经常使用的文档资源集中化,将常规的动做自动化。
在全局环境下命令行中输入dash便可启动Guide模式,输入dash -h相似命令便可支持Git模式,并已经制做了Web模式的首页。来先睹为快感觉一下:

实际上是受够了一次次花20秒钟改代码,而后花20分钟提交代码和发布的过程,尽管代码提交后的流程已经打通了jenkins的自动化流程,但代码提交前的本地工做仍然是手动的,我真的只是而已。

相关文章
相关标签/搜索