从零开始打造个人专属命令行东西集——yargs完整指南

媒介

运用敕令行递次对递次员来讲很罕见,就算是前端工程师或许开辟gui的,也须要运用敕令行来编译递次或许打包递次

闇练运用敕令行东西能极大的进步开辟效力,linux自带的敕令行东西都异常的有效,然则这些东西都是根据通用需求开辟出来的
,假如有一些迥殊的需求,照样须要本身写脚原本完成一些比方文件批量重命名,文件内容批量替代等使命来供应工作效力。

在node.js出来之前,python经常被用来开辟一些剧本完成特别的使命,比方python爬虫,python相干的教程有许多,有兴致的本身google。

得益于node.js的异步io特征,运用node开辟io麋集类使命变得异常简朴,这篇文章就为人人讲讲怎样运用node.js的yargs模块来开辟本身的敕令行东西鸠合。

敕令行参数剖析

yargs是一个npm模块用来完成敕令行参数剖析的,回到运用shell开辟敕令行的时期,getopts是第一代敕令行参数剖析东西,经由shell => python => node.js
的迭代,敕令行参数剖析递次实在没有多大的进化,它们的目标始终是把用户从敕令行传入的参数剖析成指定的花样,供递次运用

虽然没有多大变化,然则由于开辟一个敕令行参数剖析模块比较简朴,所以如今node社区存在许多相似yargs的开源项目,这里简朴枚举一下,有兴致的能够本身去相识一下,
然后挑选本身喜好的项目来运用。

yargs

读过阮一峰的Node.js 敕令行递次开辟教程以后最先运用yargs开辟本身敕令行东西,
用过一段时候发明异常的好用。

自阮大神的文章宣布以来,yargs有了一些修正,增加有许多有效的功用,迥殊是.commandDir(directory, [opts])这个功用,对打造敕令行东西鸠合异常有效,所以写一个新版本的yargs教程照样有必要的。

yargs的用法还算比较简朴,对英文有自信的能够去首页浏览原版:yargs

简朴形式

yargs默许运用两个--作为参数的前缀,中心运用空格或许=都能够

下面的代码展现了yargs最简朴的用法,你只须要引入yargs,就可以读取敕令行参数,不须要写任何的设置,异常的简朴

#!/usr/bin/env node
var argv = require('yargs').argv;

if (argv.ships > 3 && argv.distance < 53.5) {
    console.log('Plunder more riffiwobbles!');
} else {
    console.log('Retreat from the xupptumblers!');
}
$ ./plunder.js --ships=4 --distance=22
Plunder more riffiwobbles!

$ ./plunder.js --ships 12 --distance 98.7
Retreat from the xupptumblers!

示例代码都来自官网:yargs

简朴形式还能读取短变量如-x 4相当于argv.x = 4

简朴形式还能读取布尔范例-s相当于argv.s = true

简朴形式还能读取非-最先的变量,这类范例的变量保存在argv._数组内里

参数设置

简朴形式的功用都只用一行代码就可以完成

var argv = require('yargs').argv;

然则假如你想统计变量涌现的次数怎样办? 答案就是增加参数设置选项。

#!/usr/bin/env node
var argv = require('yargs')
    .count('verbose')
    .alias('v', 'verbose')
    .argv;

VERBOSE_LEVEL = argv.verbose;

function WARN()  { VERBOSE_LEVEL >= 0 && console.log.apply(console, arguments); }
function INFO()  { VERBOSE_LEVEL >= 1 && console.log.apply(console, arguments); }
function DEBUG() { VERBOSE_LEVEL >= 2 && console.log.apply(console, arguments); }

WARN("Showing only important stuff");
INFO("Showing semi-important stuff too");
DEBUG("Extra chatty mode");

上面的递次能统计verbose参数涌现的次数,缩写-v也会统计进去,详细挪用例子参考下面的代码

$ node count.js
Showing only important stuff

$ node count.js -v
Showing only important stuff
Showing semi-important stuff too

$ node count.js -vv
Showing only important stuff
Showing semi-important stuff too
Extra chatty mode

$ node count.js -v --verbose
Showing only important stuff
Showing semi-important stuff too
Extra chatty mode

yargs供应许多接口用来协助完美敕令行递次,

提醒用法

var argv = require('yargs')
    .usage('Usage: $0 -w [num] -h [num]')
    .argv;

必选参数

#!/usr/bin/env node
var argv = require('yargs')
    .usage('Usage: $0 -w [num] -h [num]')
    .demand(['w','h'])
    .argv;

供应参数默许值

#!/usr/bin/env node
var argv = require('yargs')
    .default('x', 10)
    .default('y', 10)
    .argv
;
console.log(argv.x + argv.y);

打印协助信息

#!/usr/bin/env node
var argv = require('yargs')
    .usage('Usage: $0 <command> [options]')
    .help('h')
    .alias('h', 'help')
    .epilog('copyright 2015')
    .argv;

运用别号

var argv = require('yargs')
    .usage('Usage: $0 <command> [options]')
    .alias('h', 'help')
    .argv;

接见argv.h相当于接见argv.help

参数数组

var argv = require('yargs')
    .usage('Usage: $0 <command> [options]')
    .alias('n', 'name')
    .array('n')
    .argv;

console.log(argv.n);

挪用

node array_test.js -n abc test

设置参数局限

var argv = require('yargs')
  .alias('i', 'ingredient')
  .describe('i', 'choose your sandwich ingredients')
  .choices('i', ['peanut-butter', 'jelly', 'banana', 'pickles'])
  .help('help')
  .argv

上述代码设定argv.i的值只能是['peanut-butter', 'jelly', 'banana', 'pickles']数组中的一个

上面是yargs比较简朴的用法,假如想浏览完整版,发起去github上浏览

子敕令

yargs合适开辟庞杂的敕令行递次的另一个原因是它支撑子敕令,而且子敕令能够嵌套,这意味着你也能够开辟出相似git如许具有上百个敕令的递次

yargs的子敕令有两种形式:.command(*).commandDir(directory, [opts])

.command

.command要领有三个接口

.command(cmd, desc, [builder], [handler])

.command(cmd, desc, [module])

.command(module)

实在它们的用法都差不多,能够把它们都看做通报一个module给yargs,这个module必需导出四个变量
cmd, desc [builder], [handler],个中builder和handler是要领,别的两个是字符串

运用第一个接口的示例

yargs
  .command(
    'get',
    'make a get HTTP request',
    function (yargs) {
      return yargs.option('u', {
        alias: 'url',
        describe: 'the URL to make an HTTP request to'
      })
    },
    function (argv) {
      console.log(argv.url)
    }
  )
  .help()
  .argv

运用第三个接口须要把这个模块在零丁的文件,然后用require引入

这是模块的代码

// my-module.js
exports.command = 'get <source> [proxy]'

exports.describe = 'make a get HTTP request'

exports.builder = {
  banana: {
    default: 'cool'
  },
  batman: {
    default: 'sad'
  }
}

exports.handler = function (argv) {
  // do something with argv.
}

引入的时刻如许运用

yargs.command(require('my-module'))
  .help()
  .argv

当分外的模块没有定义cmd和desc的时刻能够运用第二个接口

yargs.command('get <source> [proxy]', 'make a get HTTP request', require('my-module'))
  .help()
  .argv

这里发起运用第三个接口,如许能坚持模块的内聚,这类模块你能挂载在任何敕令下面,迁徙的时刻不须要修正模块代码,只须要修正引入模块的代码就可以完成

.commandDir

假如有大批的敕令都运用上面的.command(module)来开辟的话,这些模块都有雷同的构造,应当能有要领简化这些敕令的引入历程,把这个历程自动化,基于
这个目标yargs供应了.commandDir接口

下面参考一个我本身写的项目pit

下面是这个项目标目次构造

.
├── pit
│   ├── douban
│   │   └── movie.js
│   ├── douban.js
│   ├── gg
│   │   ├── client.js
│   │   ├── login.js
│   │   ├── scope.js
│   │   ├── scope.json
│   │   ├── secret.json
│   │   ├── token.json
│   │   └── upload.js
│   ├── gg.js
│   ├── git
│   │   ├── commit.js
│   │   ├── create.js
│   │   ├── deploy.js
│   │   ├── push.js
│   │   └── token.json
│   ├── git.js
│   ├── gm.js
│   ├── md5.js
│   ├── news
│   │   ├── bing.js
│   │   ├── funs.js
│   │   ├── funs.json
│   │   ├── games.js
│   │   ├── games.json
│   │   ├── google.js
│   │   ├── newsall.json
│   │   ├── shops.js
│   │   ├── shops.json
│   │   ├── videos.js
│   │   └── videos.json
│   └── news.js
└── pit.js

pit.js:敕令行的进口

#!/usr/bin/env node

require('yargs')
  .commandDir('pit')
  .demand(1)
  .help()
  .locale('en')
  .showHelpOnFail(true, 'Specify --help for available options')
  .argv

这段代码只指定读取同目次下同名文件夹pit下面的敕令加载为子敕令

注重:commandDir默许只会加载目次下第一级的文件,不会递归加载,假如想递归加载须要如许写.commandDir('pit', {recurse: true})

接着来看git子敕令,由于git项目每次提交都要反复几个雷同的步骤,一切想开辟一个更简朴的敕令举行打包提交

git.js


exports.command = 'git <command>';

exports.desc = 'github command list';

exports.builder = function (yargs) {
  return yargs.commandDir('git')
}

exports.handler = function (argv) {}

git也是加载一个目次作为本身的子敕令:以commit为例

commit.js

'use strict';

var fs = require('fs');
var path = require('path');

require('shelljs/global');

var Q = require('q');

function _exec(cmd) {
  var deferred = Q.defer();
  exec(cmd, function (code, stdout, stderr) {
    deferred.resolve();
  });
  return deferred.promise;
}

exports.command = 'commit';

exports.desc = 'commit repo local';

exports.builder = function (yargs) {
  return yargs
    .help('h');
};

exports.handler = function (argv) {
  var repo = process.cwd();
  var name = path.basename(repo);
  Q.fcall(function () { })
    .then(() => _exec(`git add .`))
    .then(() => _exec(`git commit -m 'd'`))
    .catch(function (err) {
      console.log(err);
    })
    .done(() => {
      console.log(`commit ${repo} done`);
    });

}

这个敕令默许运转在git项目标根目次,和git敕令不太一样,git能够在项目根目次下的恣意子目次内里运转。

运用shelljs来运转子敕令,然后用Q举行promise封装,保证敕令的实行递次,同时把敕令行输出和错误信息都打印到
掌握。

一个很简朴能节约时候的敕令行递次,作为举一反三之用

延长

高手都是善于运用敕令行(影戏内里的高手也一样),当你习气运用敕令行完成一样平常使命以后,逐步的会构成一种依靠。继续下去,你会斟酌把一切的事变都用来敕令行来完成,固然这个
目标不能完成,由于能自动完成一切使命的敕令行不叫敕令行——它叫AI

虽然不能开辟一台高智能ai,然则照样有许多使命能用敕令行来完成的,这里写下我的思绪,供人人参考

api敕令行

大型网站都供应本身的api接口配上oauth2.0认证,假如你想运用敕令行来挪用这些api接口,你完全能够做到

像aws,google cloud,aliyun这类云主机,运用敕令行能节约许多运维的时候

别的你也能够参考上面pit.js写的douban.js来抓取豆瓣的数据,豆瓣的大众api不须要认证就可以接见,用来做一些测试异常轻易

敕令行爬虫

运用node.js开辟爬虫就像运用python一样简朴,然则一个功用完全的爬虫必定少不了敕令行接口,你不可能每次有新的需求都来修正代码,下次再给人人分享我写的一个简朴的基于
node.js的爬虫项目

表单提交

对一些不供应api接口然则又想运用敕令来举行交互的网站,你能够运用表单提交来举行登录,然后做一些登录以后才做的事变:比方发表文章

如今许多的网站都支撑运用markdown编辑文章,然后宣布,对这一类网站你都能够开辟本身的敕令行一致举行治理,当你写完文章以后,只须要一个简朴
的敕令,就可以把文章同时推送到各大网站

迎接人人交换本身的主意!

个人博客地址:自在前端

    原文作者:callmelanmao
    原文地址: https://segmentfault.com/a/1190000006227402
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞