都2023年了你还不会Commander.js吗?

废话不多说对照中文地址Commander.js带大家使用Commander.

都2023年了你还不会Commander.js吗?

  • 参数
    • options
    • ‘no-’ 用法
    • 必填选项
    • 变长参数
    • 版本选项
    • 其他选项配置
    • 自定义选项处理函数
  • 命令
    • addCommand
    • 命令参数
    • 其他参数配置
    • 自定义参数
    • 搭配option使用
    • 独立的可执行(子)命令
    • 生命周期钩子
  • help的使用
    • 自定义help
    • 在出错后展示帮助信息
    • .name
    • .usage
    • .description 和 .summary
    • .parse() 和 .parseAsync()
  • 抛异常
    • 异常输出重写
  • 调试

参数

options

使用program .option('-f,--first ',这里是描述,这里是默认值)。-f是缩写,–first是全称,<>(或者[]都可以)表示first的值,第三个是描述信息,最后一个是默认值。
demo

const { program } = require('commander');

program
  .option('--first')
  .option('-s, --separator ');

program.parse();

const options = program.opts();

解析:options是选项的意思,也就是说是可选项。demo如下,这里-s和–first就是我们定义的option的key,在他们的后面就是option的值。如果只是给了’–first’,但是没有给后面<>,所以是被当做boolean值。给了<>就表示需要赋值。<>括号里面不一定是char,可以是任意值。
测试
表达式1:program .option('-f,--first') .option('-s, --separator '),输入:node index2 split -s / -f a/b/c
都2023年了你还不会Commander.js吗?_第1张图片
表达式2:program .option('-f,--first <>') .option('-s, --separator '),输入:node index2 split -s / -f a/b/c
都2023年了你还不会Commander.js吗?_第2张图片
表达式3(第四个参数用法):program .option('-p, --pizza-type ', 'flavour of pizza',12346)
在这里插入图片描述

等同用法:

serve -f 80
serve -f80 (缩写才能这么写)
serve --first 80
serve --first=80

上面的用法都是生效的,看个人习惯使用。第二个注意只有缩写才能这么写,最后一个用的比较多,因为有的时候以-开头的可能是负数。比如 --first -5 而-在表达式中是有歧义的,所以我们用--first=-5

动态获取:

  • .opts()获取本地options
  • .optsWithGlobals()返回合并的本地和全局选项值
    获取所有的options
  • .getOptionValue()和.setOptionValue()操作单个选项的值
    比如:.getOptionValue(‘first’)、program.setOptionValue(‘first’,12346)
  • .getOptionValueSource()和.setOptionValueWithSource()包括选项值的来源
    program.getOptionValueSource(‘first’)获取option的来源,在控制台输出的就是cli来源

‘no-’ 用法

**解析:**no-表示该选项的默认值为false

const { program } = require('commander');

program
  .option('--no-first', 'flavour of pizza');

program.parse();

const options = program.opts();
console.log(options);

用法:

比如我们输入node index2 --no-first
在这里插入图片描述
即使我们给值node index2 --no-first 123465此时也还是false。
其他用法:

如果当前有重复定义并且使用了,那么该值为true

program
  .option('--no-first', 'flavour of pizza')
  .option('--first', 'flavour of pizza');

当我们输入node index2 --no-first 123465 --first 7758
在这里插入图片描述

必填选项

有的时候我们要求用户必须加入某个参数才有效,那么我们可以使用.requiredOption()

program
  .requiredOption('-c, --cheese ', 'pizza must have cheese');

program.parse();

变长参数

比如我们的参数值可能不是定长的,那么可以用:

program
  .requiredOption('--first ', 'flavour of pizza');

输入:node index2 --first 1 2 3
输出:
都2023年了你还不会Commander.js吗?_第3张图片

版本选项

program.version('0.0.1');
node index2  -V

参数传递:

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

其他选项配置

如果上述option还不能满足你的要求,那么看看如下示例:

program
  .addOption(new Option('-s, --secret').hideHelp())
  .addOption(new Option('-t, --timeout ', 'timeout in seconds').default(60, 'one minute'))
  .addOption(new Option('-d, --drink ', 'drink size').choices(['small', 'medium', 'large']))
  .addOption(new Option('-p, --port ', 'port number').env('PORT'))
  .addOption(new Option('--donate [amount]', 'optional donation in dollars').preset('20').argParser(parseFloat))
  .addOption(new Option('--disable-server', 'disables the server').conflicts('port'))
  .addOption(new Option('--free-drink', 'small drink included free ').implies({ drink: 'small' }));

可以设置默认值和枚举值、对值进一步处理等等

自定义选项处理函数

这个是内部提供的处理函数依然不能应对,那么你看看下面的自定义处理函数:

function myParseInt(value, dummyPrevious) {
  // parseInt 参数为字符串和进制数
  const parsedValue = parseInt(value, 10);
  if (isNaN(parsedValue)) {
    throw new commander.InvalidArgumentError('Not a number.');
  }
  return parsedValue;
}

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

program.parse();

const options = program.opts();
if (options.float !== undefined) console.log(`float: ${options.float}`);
if (options.integer !== undefined) console.log(`integer: ${options.integer}`);
if (options.verbose > 0) console.log(`verbosity: ${options.verbose}`);
if (options.collect.length > 0) console.log(options.collect);
if (options.list !== undefined) console.log(options.list);

输出:

$ custom -f 1e2
float: 100
$ custom --integer 2
integer: 2
$ custom -v -v -v
verbose: 3
$ custom -c a -c b -c c
[ 'a', 'b', 'c' ]
$ custom --list x,y,z
[ 'x', 'y', 'z' ]

命令

上述是配置option也就是选项,接下来才是正文命令的配置,options是为了command服务的。
用法:
program.command()的第一个参数为命令名称。命令参数可以跟在名称后面,也可以用.argument()单独指定。参数可为必选的(尖括号表示)、可选的(方括号表示)或变长参数(点号表示,如果使用,只能是最后一个参数)。
使用.addCommand()向program增加配置好的子命令。

program
  .command('clone  [destination]')
  .description('clone a repository into a newly created directory')
  .action((source, destination) => {
    console.log(source,destination);
  });

输入node index2 clone wsy 123,输出:
在这里插入图片描述

addCommand

意思是向program增加配置好的子命令

命令参数

就是给command命令配置参数的方式,第一种就是.command('login [password]'),第二种就是program .arguments(' '),第三种就是通过argument分别添加,如下示例:

program
  .version('0.1.0')
  .command('login')
  .argument('', 'user to login')
  .argument('[password]', 'password for user, if required', 'no password given')
  .action((username, password) => {
    console.log('username:', username);
    console.log('password:', password);
  });

执行:node index2 login wsy 123
都2023年了你还不会Commander.js吗?_第4张图片
在参数名后加上…来声明可变参数,且只有最后一个参数支持这种用法。可变参数会以数组的形式传递给处理函数。例如:

program
  .version('0.1.0')
  .command('rmdir')
  .argument('')
  .action(function (dirs) {
    dirs.forEach((dir) => {
      console.log('rmdir %s', dir);
    });
  });

其他参数配置

可以通过.addArgument的方式添加其他参数

const commander = require("commander");
const program = new commander.Command();

program
  .addArgument(
    new commander.Argument("", "drink cup size").choices([
      "small",
      "medium",
      "large",
    ])
  )
  .addArgument(
    new commander.Argument("[timeout]", "timeout in seconds").default(
      60,
      "one minute"
    )
  );
program.parse();
console.log(program.args);

输入:node index2 small 123
都2023年了你还不会Commander.js吗?_第5张图片

自定义参数

自定义参数处理函数中的返回值会交给action,作为函数的入参。

const commander = require("commander");
const program = new commander.Command();

const myParseInt =function(param){
  return parseInt(param)
}

program
  .command('add')
  .argument('', 'integer argument', myParseInt)
  .argument('[second]', 'integer argument', myParseInt, 1000)
  .action((first, second) => {
    console.log(`${first} + ${second} = ${first + second}`);
  })
;
program.parse();

输入:node index2 add 1 2.1,输出:
都2023年了你还不会Commander.js吗?_第6张图片

搭配option使用

搭配option使用时,action中的入参先罗列argument,再将options的参数作为对象放入

program
  .argument("")
  .argument("")
  .option("-t, --title ", "title to use before name")
  .option("-s, --set ", "title to use before name")
  .action((name,age, options, command) => {
    if (options.debug) {
      console.error("Called %s with options %o", command.name(), options);
    }
    const title = options.title ? `${options.title} ` : "";
    console.log(`Thank-you ${title}${name}`);
  });

输入:node index2 wsy 23 -t lvyou -s 777,输出:
都2023年了你还不会Commander.js吗?_第7张图片
options是一个对象,argument是单个的入参。但是我们一般习惯顺序command=>argument=>option=>action:

program
  .command('serve')
  .argument('
                    
                    

你可能感兴趣的:(javascript,前端,开发语言)