Search code examples
javascriptnode.jsargsyargs

why yargs.argv causes handler function to invoke


const yargs = require("yargs");

yargs.version = "1.0.0";

yargs.command({
  command: "add",
  describe: "do addition ",
  handler: function () {
    console.log("addition complete");
  },
}).argv;

In the above code using yargs i was trying to create a command add and on running the script with node . add the handler function is executed and i get the the expected output

$ node . add
addition complete

but when the same code is run without the .argv the output is blank and the handler function is not executed . in the docs it is not stated what .argv is , weather its an object or a function and how it actually works . at first glance it looks like a normal method invocation but

When you do the following
console.log(typeof yargs.argv);

The output is

$ node . add
addition complete
object

If yargs.argv is an like any other Object then just by accessing it how and why it is able to invoke a function

can somebody explain whats actually happening and where am i missing out .


Solution

  • Yargs is using a #getter, this allows javascript to call a function when a property is called.

    Example:

    const obj = {
      log: ['a', 'b', 'c'],
      get latest() {
        if (this.log.length === 0) {
          return undefined;
        }
        return this.log[this.log.length - 1];
      }
    };
    
    console.log(obj.latest);
    // expected output: "c"
    

    If you look at the source code you can see when you call .argv, yargs just calls .parse():

     const yargs = new YargsInstance(processArgs, cwd, parentRequire, _shim);
     // Legacy yargs.argv interface, it's recommended that you use .parse().
     Object.defineProperty(yargs, 'argv', {
         get: () => {
            return yargs.parse();
          },
         enumerable: true,
    });