Search code examples
javascriptcommand-line-interfaceyargs

Optional argument to option with yargs


I am trying to build a command-line interface with yargs, where one option takes an (optional!) argument:

const cli = yargs
.array('keyword')
.option('keyword', {
    alias: 'k',
    type: 'string',
    describe: 'add additional keyword or clear previous keywords without an argument'
)
.argv;

In other words the usage program --keyword --keyword=this --keyword=that is accepted.

How can I tell yargs to accept the option --keyword with or without an option?


Solution

  • It turns out that yargs will always accept empty arguments to options. The behavior differs depending on whether the option is an array option or not.

    If you run programm --keyword --keyword=this --keyword=that and if you define your options like this:

    const cli = yargs
    .array('keyword')
    .option('keyword', {
        alias: 'k',
        type: 'string',
    
    })
    .argv;
    console.log(yargs)
    

    You get this output:

    {
      _: [],
      keyword: [ 'this', 'that' ],
      k: [ 'this', 'that' ],
      '$0': 'bin/program.js'
    }
    

    The option without an argument is simply ignored which is likely not what you want.

    Without array:

    const cli = yargs
    .option('keyword', {
        alias: 'k',
        type: 'string',
    
    })
    .argv;
    console.log(yargs)
    

    You get this output:

    {
      _: [],
      keyword: [ '', 'this', 'that' ],
      k: [ '', 'this', 'that' ],
      '$0': 'bin/program.js'
    }
    

    That means that the empty argument is saved in the result.