阅读 4185

Commander.js 中文文档(cli必备)

Commander.js node.js命令行界面的完整解决方案,受 Ruby Commander启发。

前端开发node cli 必备技能。

Install

    $ npm install commander
复制代码

API

version

var program = require('commander');
 
program
    .version('0.0.1')
    .parse(process.argv);
    
#执行结果:
node index.js -V
 
0.0.1
#如果希望程序响应-v选项而不是-V选项,
#只需使用与option方法相同的语法将自定义标志传递给version方法
program
  .version('0.0.1', '-v, --version')
复制代码

option

  • 使用.option()方法定义commander的选项options
  • 示例:.option('-n, --name <items1> [items2]', 'name description', 'default value')
  • 参数解析:
  1. 自定义标志<必须>:分为长短标识,中间用逗号、竖线或者空格分割;标志后面可跟必须参数或可选参数,前者用<>包含,后者用[]包含
  2. 选项描述<省略不报错>:在使用 --help 命令时显示标志描述
  3. 默认值<可省略>
  4. 短标志可以作为单独的参数传递。像 -abc 等于 -a -b -c。多词组成的选项,像“--template-engine”会变成 program.templateEngine 等。

command

  • 作用:添加命令名称,
  • 示例:.command('add <num> [otherDirs...]', 'install description', opts)
  • 参数解析:
  1. 命令名称<必须>:命令后面可跟用 <> 或 [] 包含的参数;命令的最后一个参数可以是可变的,像实例中那样在数组后面加入 ... 标志;在命令后面传入的参数会被传入到 action 的回调函数以及 program.args 数组中
  2. 命令描述<可省略>:如果存在,且没有显示调用action(fn),就会启动子命令程序,否则会报错
  3. 配置选项<可省略>:可配置noHelp、isDefault等

alias description usage

定义命令的别名 描述和用法

.alias('r')
.usage('[options] <file ...>')
.description('run setup commands for all envs')

#output
gp-cli rm --help
Usage: rm|r [options] <file ...>

run setup commands for all envs

Options:

  -r, --recursive     Remove recursively
  -d --drink [drink]  Drink
  -h, --help          output usage information
复制代码

action

定义命令的回调函数 用法示例:.action(fn)

program
	.command('rm <dest> [otherDirs...]')
	.alias('r')
	.option('-r, --recursive', 'Remove recursively')
	.option('-d --drink [drink]', 'Drink','Beer')
	.action(function (d, otherD,cmd) {
		console.log('remove ' + d ,(cmd.drink ),(cmd.recursive ))
		if (otherD) {
			otherD.forEach(function (oDir) {
				console.log('rmdir %s', oDir);
			});
		}

	})
#output
 ✗ gp-cli rm ./aa bb cc  -d -r
remove ./aa Beer true
rmdir bb
rmdir cc
复制代码

Eg:

自定义校验

function range(val) {
  return val.split('..').map(Number);
}
 
function list(val) {
  return val.split(',');
}
 
function collect(val, memo) {
  memo.push(val);
  return memo;
}
 
function increaseVerbosity(v, total) {
  return total + 1;
}
 
program
  .version('0.1.0')
  .usage('[options] <file ...>')
  .option('-i, --integer <n>', 'An integer argument', parseInt)
  .option('-f, --float <n>', 'A float argument', parseFloat)
  .option('-r, --range <a>..<b>', 'A range', range)
  .option('-l, --list <items>', 'A list', list)
  .option('-o, --optional [value]', 'An optional value')
  .option('-c, --collect [value]', 'A repeatable value', collect, [])
  .option('-v, --verbose', 'A value that can be increased', increaseVerbosity, 0)
  .parse(process.argv);
 
console.log(' int: %j', program.integer);
console.log(' float: %j', program.float);
console.log(' optional: %j', program.optional);
program.range = program.range || [];
console.log(' range: %j..%j', program.range[0], program.range[1]);
console.log(' list: %j', program.list);
console.log(' collect: %j', program.collect);
console.log(' verbosity: %j', program.verbose);
console.log(' args: %j', program.args);


# 执行结果
node index.js -i 1.2 -f 1.2 -r 1..2 -l a,b -o hehe -c heihei -v zeze
 
 int: 1
 float: 1.2
 optional: "hehe"
 range: 1..2
 list: ["a","b"]
 collect: ["heihei"]
 verbosity: 1
 args: ["zeze"]
复制代码

正则表达式

program
  .version('0.1.0')
  .option('-s --size <size>', 'Pizza size', /^(large|medium|small)$/i, 'medium')
  .option('-d --drink [drink]', 'Drink', /^(coke|pepsi|izze)$/i)
  .parse(process.argv);
 
console.log(' size: %j', program.size);
console.log(' drink: %j', program.drink);

# 执行结果
node index.js -s hahah -d hehe
 
 size: "medium"
 drink: true
 #size 没有输入值则报错,不符合正则则为默认值,符合正则则为size
 #drink 没有输入则报undefined,不符合正则则为true,符合正则则为drink
复制代码

Variadic arguments可变参数

命令command有且只有最后一个参数可变不固定的。 要使参数变量可变,必须将...附加到参数名称。

var program = require('commander');
 
program
  .version('0.1.0')
  .command('rmdir <dir> [otherDirs...]')
  .action(function (dir, otherDirs) {
    console.log('rmdir %s', dir);
    if (otherDirs) {
      otherDirs.forEach(function (oDir) {
        console.log('rmdir %s', oDir);
      });
    }
  });
 
program.parse(process.argv);

#执行结果
node index.js rmdir ./hahah aaa bbb ccc
 
rmdir ./hahah
rmdir aaa
rmdir bbb
rmdir ccc
# 可变参数的值保存在数组中, 通过program.args以及传递action的参数获取。
复制代码

指定参数语法 Specify the argument syntax

#!/usr/bin/env node
 
var program = require('commander');
 
program
  .version('0.1.0')
  .arguments('<cmd> [env]')
  .action(function (cmd, env) {
     cmdValue = cmd;
     envValue = env;
  });
 
program.parse(process.argv);
 
if (typeof cmdValue === 'undefined') {
   console.error('no command given!');
   process.exit(1);
}
console.log('command:', cmdValue);
console.log('environment:', envValue || "no environment given");

#执行结果
node arguments.js aaa ccc

command: aaa
environment: ccc
复制代码

Git风格的子命令

当 .command() 带有描述参数时,不能采用 .action(callback) 来处理子命令,否则会出错。这告诉 commander,你将采用单独的可执行文件作为子命令。例如运行gp-cli rm会搜索同级目录下面的gp-cli-rm

#pm 文件内容
program
  .version('0.0.1')
  .description('Fake package manager')
  .command('install [name]', 'install one or more packages').alias('i')
  .command('search [query]', 'search with optional query').alias('s')
  .command('list', 'list packages installed')
  .command('publish', 'publish the package').alias('p')
  .parse(process.argv);

# pm-install 文件内容  
#!/usr/bin/env node
var program = require('..');

program
  .option('-f, --force', 'force installation')
  .parse(process.argv);

var pkgs = program.args;

if (!pkgs.length) {
  console.error('packages required');
  process.exit(1);
}

console.log();
if (program.force) console.log('  force: install');
pkgs.forEach(function(pkg){
  console.log('  install : %s', pkg);
});
console.log();  
#output:
node ./examples/pm install foo bar baz --force

  force: install
  install : foo
  install : bar
  install : baz
复制代码

自定义帮助

你可以通过监听 --help 来控制 -h, --help 显示任何信息。一旦调用完成, Commander 将自动退出,你的程序的其余部分不会展示。例如在下面的 “stuff” 将不会在执行 --help 时输出。

var program = require('commander');
 
program
  .version('0.1.0')
  .option('-f, --foo', 'enable some foo')
  .option('-b, --bar', 'enable some bar')
  .option('-B, --baz', 'enable some baz');
 
// must be before .parse() since
// node's emit() is immediate
 
program.on('--help', function(){
  console.log('')
  console.log('Examples:');
  console.log('  $ custom-help --help');
  console.log('  $ custom-help -h');
});
 
program.parse(process.argv);
 
console.log('stuff');

# output
node index.js -h
 
Usage: index [options]
 
Options:
  -V, --version  output the version number
  -f, --foo      enable some foo
  -b, --bar      enable some bar
  -B, --baz      enable some baz
  -h, --help     output usage information
 
Examples:
  $ custom-help --help
  $ custom-help -h
复制代码

.outputHelp(cb)

输出帮助信息而不退出。 回调cb允许在显示帮助文本之前对其进行后处理。如果要在默认情况下显示帮助(例如,如果未提供command),则可以使用以下内容:

var program = require('commander');
var colors = require('colors');
 
program
  .version('0.1.0')
  .command('getstream [url]', 'get stream URL')
  .parse(process.argv);
 
if (!process.argv.slice(2).length) {
  program.outputHelp(make_red);
}
 
function make_red(txt) {
  return colors.red(txt); //display the help text in red on the console
}
复制代码

help(cb)

自定义事件监听,回调cb允许在显示帮助文本之前对其进行后处理。

program.on('option:verbose', function () {
  console.log(this.verbose)
  process.env.VERBOSE = this.verbose;
});

// error on unknown commands
program.on('command:*', function () {
  console.error('Invalid command: %s\nSee --help for a list of available commands.', program.args.join(' '));
  process.exit(1);
});

#alternative
// program
//   .command('*')
//   .action(function(env){
//     console.log('deploying "%s"', env);
//   });
  
#output
✗ node ./examples/deploy dd aa
Invalid command: dd aa
See --help for a list of available commands.

✗ node ./examples/deploy --verbose
true
复制代码