commander.js Principle analysis

hoperyy 2021-02-23 04:05:01
commander.js commander js principle analysis

The original is published in Github: hoperyy blog


commander.js 7.0.0 Version of the core code is just a file index.js,2200 Many lines of code , The comments of the code are quite rich , Code readability is also good , Interested students can read through .

commander.js Contains the following classes :

  • Option
  • Help
  • Command
  • CommandError
  • InvalidOptionArgumentError

Here's the picture :

Option class

Options Class to store all kinds of information about options :

  • Whether the option is required (requred)
  • Description information (description)
  • Variable parameters (variadic)
  • Whether it's reverse boolean, That is to say --no-xx Type options
  • long name / Short name , That is to say -c, --cheese
  • The value of the parameter
  • other


Command line instance execution program.option("-c, --cheese", "add cheese"), It will create a new one Option example , Store all kinds of information about this option .

Option Class internal through a variety of regular and string calculation of all kinds of information .

such as ,Option There are three ways to write the long and short names of class acceptance parameters :

  • "-c, --cheese"
  • "-c|--cheese"
  • "-c --cheese"

When it parses the parameters, it is regular /[ |,]+/ Separate strings : flags.split(/[ |,]+/).

Help class

Help Class is mainly responsible for the display of help information 、 Configuration and other work .

Like executing the command line node index.js -h Will print out the :

Usage: index [options]
-v, --version output the version number
-d, --debug output extra debugging
-c, --cheese <type> cheese type (default: "blue")
-b, --banana [type] banana type
-i, --integer <number> integer argument
-h, --help display help for command
 Copy code 

Help The relative worth of saying in class is formatHelp The method .

formatHelp Receive the current command line and help Instance object , Return the formatted help information .

In the process of generating help information , There are a few small programming skills to learn from :

  • Log information string , Organize... In the form of arrays , The final splice is a string

    This method is compared with direct splicing string , More maintainable code .

  • utilize String.prototype.padEnd Method to complete a string

    There may not be many scenarios using this method in daily work , Easy to miss .

    such as :'hello'.padEnd(7, '~') The result is hello~~.

    stay formatHelp Fill in the blanks in , Formatting for string display .

Command class

Command Class is commander.js The core of the class , Provides various methods of the command line .

The picture below is Command The main process of using class :

Let's briefly introduce some of them :

  • version(str, flags, description)

    This method registers the version information of the command , utilize createOption() A quick way to implement .

  • command(nameAndArgs, actionOptsOrExecDesc, execOpts)

    This method registers the subcommand , There are two patterns :

    • Bind functions to implement commands

      .action(function() {
       Copy code 

      perform node index start When , Will execute action Registered callbacks , Print actor.

    • Start the stand-alone file to execute the command

      program.command('start', 'start runner');
       Copy code 

      perform node index start When , It will start index-start.js file .

    This method determines which mode it is by whether it contains description information .

  • When the registration command is repeated , Will use the first registered command

    such as :

    .action(function() {
    console.log('start 1');
    .action(function() {
    console.log('start 2');
     Copy code 

    In execution node index start When , Only print start 1, Because the code to find the matching command is :

    this.commands.find(cmd => cmd._name === name || cmd._aliases.includes(name));
     Copy code 

    Array.prototype.find Method returns the first matching element of the array .

  • EventEmitter stay Command Class

    Node Built-in module EventEmitter Provides an event mechanism , The most common api yes on/emit.

    Command There are several examples of using event mechanism in class :

    • When registering option parameters , registers option:${optionName} event (on(option:${optionName})), Trigger a callback when the command line executes (emit(option:${optionName})).
    • When executing an order , If there is no matching command , Will pass this.listenerCount('command:*') obtain command:xx event (* For wildcard ) The number of listeners , Decide whether to trigger the event

Error class

The picture below is Commander.js A few of the internal definitions Error Class inheritance .


On the internal implementation , Each class's own special fields are defined . But here's the thing ,Error.captureStackTrace(this, this.constructor) It's used a lot .

  • Error.captureStackTrace Use

    Error.captureStackTrace(targetObject[, constructorOpt])

    Its function is to targetObject Add a stack attribute . When accessing targetObject.stack when , Will return... As a string Error.captureStackTrace Code location information when the method is called . give an example :


    > 1 const myObject = {};
    > 2 Error.captureStackTrace(myObject);
    > 3 console.log(myObject.stack);
     Copy code 

    perform node index.js after , Terminal output :

    at Object.<anonymous> (xxx/index.js:2:7)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at ...
    at ...
     Copy code 

    When it comes to constructorOpt when , Code such as :

    > 1 function MyError() {
    > 2 Error.captureStackTrace(this, MyError);
    > 3 }
    > 4
    > 5 console.log(new MyError().stack)
     Copy code 

    Terminal output :

    at Object.<anonymous> (xxx/index.js:5:13)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at ...
    at ...
     Copy code 

    It can be seen that ,MyError The stack details inside the function are hidden .

  • Error.captureStackTrace advantage

    be relative to new Error().stack,Error.captureStackTrace It has the following advantages :

    • More concise

      There is no need to new A new Error object , Save memory space , At the same time, the code will be more elegant .

      generally speaking , The usual way to capture error messages is :

      try {
      new Error();
      } catch(err) {
      // err.stack Contains stack information , It can be dealt with 
       Copy code 

      While using Error.captureStackTrace You can get stack information directly , The implementation is simpler .

    • More secure

      If you need to ignore part of the stack information , Use Error.captureStackTrace It will be more convenient , No manual operation is required .

    • Less resources

      Use Error.captureStackTrace when , Only visit targetObject.stack when , Then we can format the stack information .

      If targetObj.stack Not visited , The formatting of stack information will be omitted , To save computing resources .

  • Error.captureStackTrace Use scenarios

    Error.captureStackTrace Not at all Node.js To create the , It is V8 Engine Stack Trace API. Grammatically ,Node.js Medium Error.captureStackTrace() And V8 The interfaces exposed in the engine are exactly the same .

    in fact ,Node.js Of Error Class , All and stack trace The content depends on V8 Of Stack Trace API.

    therefore ,Error.captureStackTrace(targetObject[, constructorOpt]) The scenarios used are :

    • be based on V8 The running environment of the engine , Such as Node.js、Chrome browser

    • Error.captureStackTrace(this, MyError)

      It is also used to hide the stack information inside the constructor , But you need to explicitly specify the constructor name , Not very versatile .

    • Error.captureStackTrace(this, arguments.callee)

      arguments.callee Represents the current function , There's also versatility . but ES3 And then the strict mode is disabled arguments.callee, Therefore, it is not recommended to use .

    • Error.captureStackTrace(this, this.constructor)

      This method can hide the stack information inside the constructor , There is no need to specify the constructor name , Universal strong .


  1. JavaScript advanced: Javascript object-oriented, JavaScript built-in object, JavaScript BOM, JavaScript encapsulation
  2. JavaScript advanced: Javascript object-oriented, JavaScript built-in object, JavaScript BOM, JavaScript encapsulation
  3. Vue determines whether the El form in the elementui is updated or changed. If it changes, it will prompt whether to save it. If it does not change, it will leave directly
  4. Algorithm problem: sum of two numbers -- JavaScript and Java implementation
  5. High performance nginx HTTPS tuning
  6. JQuery advanced
  7. day 30 jQuery
  8. JQuery:JQuery Basic syntax, jQuery selector, jQuery DOM, comprehensive case check box, comprehensive case random picture
  9. TCP/IP 开胃菜 之 HTTP
  10. JQuery:JQuery Basic syntax, jQuery selector, jQuery DOM, comprehensive case check box, comprehensive case random picture
  11. JavaScript data type
  12. [micro front end] the final chapter of micro front end - Qiankun guide and overall exploration of micro front end
  13. Solve Ajax cross domain problem [5 solutions]
  14. HTTP of TCP / IP appetizer
  15. Optimization of pod creation efficiency in serverless scenario
  16. Iqiyi Sports: experience the ultimate expansion and contraction of serverless, and increase the utilization rate of resources by 40%
  17. First knowledge of HTTP / 1.1
  18. First knowledge of HTTP / 1.1
  19. Webpack learning notes series 05 devserver
  20. Webpack learning notes series 04 - resource processing optimization
  21. How to build a high performance front end intelligent reasoning engine
  22. How to become a professional front end engineer in 2021?
  23. How to transform single / micro service application into serverless application
  24. How to transform single / micro service application into serverless application
  25. How to transform single / micro service application into serverless application
  26. How to connect the ground gas to the micro front end?
  27. How to connect the ground gas to the micro front end?
  28. How to connect the ground gas to the micro front end?
  29. Vue server rendering principle analysis and introduction
  30. Realize the correct loading of text message
  31. Building my own project scaffolding with yeoman
  32. JavaScript advanced prototype and prototype chain
  33. React background management front end system (based on open source framework development) start
  34. JS practical skills breakpoint debugging
  35. I'd like to share with you 20 super easy-to-use Chrome extension plug-ins
  36. Get page element location
  37. Use the powerful API of modern browser to record any interface in the browser and realize export, save and management
  38. Delayed code execution in flutter
  39. Reconfiguration experience of KOA middleware system
  40. Add comments to your blog
  41. Svg editor -- new path
  42. Detailed explanation of debounce and throttle of JavaScript function
  43. Anti shake and throttling and corresponding react hooks package
  44. C2m: the first CSDN article moved to MOOC script 5000 words, detailed painstaking development process, there are renderings and source code at the end of the article
  45. Front end, school recruitment, Taobao, guide
  46. [vue2 & G6] get started quickly
  47. Canvas from the beginning to the pig
  48. Take five minutes to standardize the code comments?
  49. Some thoughts on sass
  50. what?! You haven't filled in the award information yet
  51. How to get the interface + tsdoc needed by TS through swagger
  52. Binary tree
  53. Canvas drawing method in Web screenshot
  54. Front end docker image volume optimization (node + nginx / node + multi-stage construction)
  55. Become a big influence of technology? Coding pages quickly build personal blog
  56. Object and array deconstruction, spread operator, rest operator
  57. Analysis of Axios source code
  58. Two ways to delete useless code in project (Practical)
  59. Edit your picture with canvas
  60. Today's chat: 2-4 years to walk out of the resignation dilemma and comfort zone