You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用Commander.js时全局选项在子命令前执行顺序异常问题

解决Commander.js全局参数与子命令执行顺序问题

我懂你遇到的这个困扰——明明把全局参数--hello放在子命令前面,结果子命令的输出反而先跑出来了,完全和预期顺序反过来了对吧?

问题根源

这是Commander.js的默认执行逻辑导致的:当调用program.parse(process.argv)时,程序会优先识别并执行子命令的action回调函数,等子命令的逻辑跑完之后,才会去处理你写在parse之后的全局参数判断代码,所以输出顺序自然就和你预期的相反了。

解决方案

要让全局参数的逻辑先执行,你可以用Commander.js提供的**preAction钩子**,这个钩子会在所有子命令的action执行前触发,刚好匹配你的需求。

修改后的代码如下:

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

program
  .version('0.0.1','-V, --version')
  .option('-h, --hello','print hello')

program
  .command('msg')
  .option('-w, --world','print world')
  .action(function(options){
    console.log("inside subcommand");
    if(options.world){
      console.log("world");
    }
  });

// 新增preAction钩子,在子命令action前执行全局参数逻辑
program.hook('preAction', (thisCommand) => {
  if (thisCommand.parent.hello) { // 通过parent获取全局参数
    console.log("hello");
  }
});

program.parse(process.argv);

验证效果

当你执行命令node your-file.js --hello msg --world时,输出就会和你预期的完全一致:

hello
inside subcommand
world

补充思路

如果不想用钩子,也可以把全局参数的处理逻辑封装成函数,在每个子命令的action开头先调用这个函数,但这种方式在多子命令场景下会重复代码,远不如钩子来得优雅。

内容的提问来源于stack exchange,提问作者Shivam Kumar

火山引擎 最新活动