node插件之commander

429 阅读4分钟

参考demo:


const program = require("commander");

program.version("0.0.1", "-v, --version", "output the current version");

function collect(value, previous) {
  return previous.concat([value]);
}

program
  .option(
    "--type <type...>",
    "What do you like to drink? We have black-tea, green-tea, flower-tea, milk-tea and juice",
    ['black-tea']
  )
  .option("-n, --number <number...>", "How much do you need?", [1])
  .option("-s, --size <size...>", "Select size: large, medium and small", ['medium'])
  .option(
    "-S, --sugar <sugar...>",
    "Select sugar content: less, normal and more",
    ['normal']
  )

  .action(function (list) {
    const type = list.type,
      number = list.number,
      size = list.size,
      sugar = list.sugar;

    console.log("\nYour have ordered: \n");

    if(type && type.length > 0) {
      type.forEach((value, index) => {
        console.log(
          `${number[index]} ${size[index]} cups of ${value} with ${sugar[index]} sugar\n`
        );
      });
    }
  });

program.on("--help", () => {
  console.log("\nFor example:");
  console.log("order --type black-tea -n 3 -s medium -S less\n");
});

program.parse(process.argv);

以上demo保存为index.js,然后终端进入index.js所在文件夹,执行以下命令:

node index.js
输出:
Your have ordered:

1 medium cups of black-tea with normal sugar

node index.js --type black-tea green-tea milk-tea juice -n 1 3 5 7 -s large medium small large -S less normal more more
输出:
Your have ordered:

1 large cups of black-tea with less sugar

3 medium cups of green-tea with normal sugar

5 small cups of milk-tea with more sugar

7 large cups of juice with more sugar
  • Commander 使用.option() 方法来定义选项,同时可以附加选项的简介。每个选项可以定义一个短选项名称(-后面接单个字符)和一个长选项名称(--后面接一个或多个单词),使用逗号、空格或|分隔。此方法有四个参数,第一个参数为选项命令,第二个参数为描述,第三个参数为选项处理函数,第四个选项为默认值,如果不传处理函数的话,第三个参数就是默认值。

  • 有两种最常用的选项,一类是 boolean 型选项,选项无需配置参数,另一类选项则可以设置参数(使用尖括号<>声明,则为必填项,使用方括号[]声明,则为可选项)。例如:

program
 .option('-d, --debug', 'output extra debugging')
 .option('-p, --pizza-type <type>', 'flavour of pizza');

此处第一个option为boolean型选项,第二个option为设置了参数的选项 如果在命令行中不指定具体的选项及参数,则会被定义为undefined。

  • 选项可以设置一个默认值,例如:
program.option('-c, --cheese <type>', 'add the specified type of cheese', 'blue');

此处的默认值为blue

  • 当选项为boolean类型时,在选项长名字前加no-可以配置这个选项(带 no-)的默认值为false,原选项(不带no-)默认为true,需要注意的是,仅有单独定义这种形式的选项才能有这种效果。如果先定义了--foo,那么--no-foo并不会改变它本来的默认值。可以为一个boolean类型的选项指定一个默认的布尔值,在命令行里可以重写它的值。例如:
program.option('--no-sauce', 'Remove sauce')

此处命令行不填--no-sauce的话,sauce的值就是true,填了的话,值就是false。

  • 选项的参数可以通过自定义函数来处理,该函数接收两个参数:用户新输入的参数和当前已有的参数(即上一次调用自定义处理函数后的返回值),返回新的选项参数。示例:
function myParseInt(value, dummyPrevious) {
  // parseInt takes a string and an optional radix
  return parseInt(value);
}

function increaseVerbosity(dummyValue, previous) {
  return previous + 1;
}

function collect(value, previous) {
  return previous.concat([value]);
}

function commaSeparatedList(value, dummyPrevious) {
  return value.split(',');
}

program
  .option('-f, --float <number>', 'float argument', parseFloat)
  .option('-i, --integer <number>', 'integer argument', myParseInt)
  .option('-v, --verbose', 'verbosity that can be increased', increaseVerbosity, 0)
  .option('-c, --collect <value>', 'repeatable value', collect, [])
  .option('-l, --list <items>', 'comma separated list', commaSeparatedList)
;

program.parse(process.argv);

if (program.float !== undefined) console.log(`float: ${program.float}`);
if (program.integer !== undefined) console.log(`integer: ${program.integer}`);
if (program.verbose > 0) console.log(`verbosity: ${program.verbose}`);
if (program.collect.length > 0) console.log(program.collect);
if (program.list !== undefined) console.log(program.list);
  • 通过.requiredOption方法可以设置选项为必填。必填选项要么设有默认值,要么必须在命令行中输入,对应的属性字段在解析时必定会有赋值。该方法其余参数与.option一致。

  • 定义选项时,可以通过使用...来设置参数为可变长参数。在命令行中,用户可以输入多个参数,解析后会以数组形式存储在对应属性字段中。在输入下一个选项前(-或--开头),用户输入的指令均会被视作变长参数。与普通参数一样的是,可以通过--标记当前命令的结束。示例:

program.option('-n, --number <numbers...>', 'specify numbers')
 .option('-l, --letter [letters...]', 'specify letters');
console.log('Options: ', program.opts());
$ order -n 1 2 3 --letter a b c
Options:  { number: [ '1', '2', '3' ], letter: [ 'a', 'b', 'c' ] }
  • version方法可以设置版本,其默认选项为-V和--version,设置了版本后,命令行会输出当前的版本号。版本选项也支持自定义设置选项名称,可以在version方法里再传递一些参数(长选项名称,描述信息),用法与option方法类似。例如:
program.version('0.0.1', '-v, --vers', 'output the current version');
  • 通过.command()或.addCommand()可以配置命令,有两种实现方式:为命令绑定处理函数,或者将命令单独写成一个可执行文件。.command()的第一个参数可以配置命令名称及参数,参数支持必选(尖括号表示)、可选(方括号表示)及变长参数(点号表示,如果使用,只能是最后一个参数)。使用.addCommand()向program增加配置好的子命令。
program.command('clone <source> [destination]')
  .description('clone a repository into a newly created directory')
  .action((source, destination) => {
    console.log('clone command called');
  });
program.addCommand(build.makeBuildCommand());  
  • 通过.arguments可以为最顶层命令指定参数,对子命令而言,参数都包括在.command调用之中了。尖括号(例如)意味着必选,而方括号(例如[optional])则代表可选。
program.version('0.1.0')
  .arguments('<cmd> [env]')
  .action(function (cmd, env) {
    cmdValue = cmd;
    envValue = env;
  });
  • 设置处理函数的命令可以配置选项。 命令处理函数的参数为该命令声明的所有参数,除此之外还会附加一个额外参数:该命令对象自身,配置的选项会绑定到这个对象的同名属性上。
program.command('rm <dir>')
  .option('-r, --recursive', 'Remove recursively')
  .action(function (dir, cmdObj) {
    console.log('remove ' + dir + (cmdObj.recursive ? ' recursively' : ''))
  })
  • 通过监听--help可以自定义帮助信息。
program.on('--help', () => {
  console.log('');
  console.log('Example call:');
  console.log('  $ custom-help --help');
});

此处打印的内容将会添加在与原本--help输出内容的后面。