Parse Flags and Args in Node.js CLIs with Oclif and TypeScript

Shawn Wang
InstructorShawn Wang
Share this video with your friends

Social Share Links

Send Tweet
Published 4 years ago
Updated 3 years ago

Flags and Args are the standard means of user input into CLI's. Oclif helps you parse them and declaratively indicate requirements, but because they are a public API, some thought should be put into designing the user experience. When in doubt, Flags win Arguments.

Instructor: [0:00] Let's have a look at the basic structure of an oclif command. All oclif commands are located inside of the source directory. For the single command project, I have it in index.ts. Every oclif command imports the command class from @oclif/command package. Then we extend it and export it. That's how the command is declared.

[0:28] The command has some static fields, some of which are used here. There are others that are featured in the documentation. In particular, we're going to be focusing on flags and arguments. First, let's talk about args. Args are essentially positional arguments within your CLI. They are specified just in order and parsed based on order.

[0:56] You can access them with destructuring args from this.parse. You can log them out to see what they are. Over here, I'm going to run yarn mycli. Hello world. If you take the args value from this.parse, you're going to get every argument in an object with a key based on the name that you specify.

[1:32] You may actually want variable numbers of arguments, like yarn mycli foo bar baz qux. In that case, you don't necessarily know ahead of time how many args you're going to have. You can just take the argv parameter and actually just use an array. That would work similarly as well.

[1:56] You do get an error because this is not the default in oclif. They want to encourage statically knowing everything. You can turn off the static argument with static strict equals false. Now you have variable-length arguments in your CLI. This is not the default. It's not something that oclif is trying to encourage.

[2:18] Apart from args, we also have flags. Flags are essentially named args. Because they're named, they're position-independent, which is very handy for not screwing up your CLI commands.

[2:35] As you can probably tell, there is a strong bias in oclif, and personally as well, that flags are better than arguments in almost every respect unless you have a very simple argument, like a filename that you want to pass in. Otherwise, you should probably always use flags when in doubt.

[2:53] There are a lot of nuances to parsing flags. For example, by convention within the world of CLIs, a --version flag should run the version. A --help flag should offer some basic help. Oclif helps you format the help accordingly over here.

[3:17] All the other flags are arbitrary for you to specify for your business logic internally. For example, if I were to specify a flag name of Bulbasaur, I should be able to specify it with yarn mycli --name Bulbasaur and get back a useful flags.name variable that I can just use inside of my business logic.

[3:47] Equally, I can also specify --name=Bulbasaur so there's no spacing involved and no confusion there. That should also parse accordingly. Equally as well, I should be able to specify -n, short for the name parameter. It shouldn't matter whether I have the equal sign or not.

[4:09] These are all the things that oclif helps you to take care of because these are conventions within the CLI world. The only thing that really matters is that they all resolve to a variable that you can access called flags.name. That's very helpful. You can even specify the type of the variable that will be passed back.

[4:30] For example, if you say that this is a Boolean flag, you won't get a string of true or false. You would just get an actual JavaScript true or false. You can specify a number, or you can specify a string as well. All of these are very helpful parsers that you might not think about when implementing a naïve CLI but you're definitely going to want in any sort of production setting.

[4:57] There are other parameters that you can set. For example, you can set the default parameters for some of these. For example, if I set flags, the name flag, to have a default of people. Now when I leave out the name flag and I just run my CLI, it's going to use the default that was specified within this code.

[5:27] For a full list of options for flags in arguments, you can always check back to the docs. Here are some of the standard fields, like whether the args are required or not, whether it's hidden from help files. You don't want to exactly publicize it yet. You can process your input before it's output to the final Node.js code.

[5:58] You can add a default, or you can have a set list of options. The flags have a few more available options as well. You can also have mutual dependencies or exclusive dependencies.

[6:12] You can also draw the flag from an environment variable so that if the user happens to choose, for example, like a name environment variable and then run your CLI, it still runs. It still resolves accordingly. That's a very handy feature as well.

[6:30] For more custom use cases, you can even define your own flags. That has its own parsing and validation that you can choose to have as well. As you write CLIs, you will find that flags and arguments are not the only ways to specify user input into your CLIs, but they are the default way to pass in user input from the command line. This is definitely a great place to start.

egghead
egghead
~ 2 minutes ago

Member comments are a way for members to communicate, interact, and ask questions about a lesson.

The instructor or someone from the community might respond to your question Here are a few basic guidelines to commenting on egghead.io

Be on-Topic

Comments are for discussing a lesson. If you're having a general issue with the website functionality, please contact us at support@egghead.io.

Avoid meta-discussion

  • This was great!
  • This was horrible!
  • I didn't like this because it didn't match my skill level.
  • +1 It will likely be deleted as spam.

Code Problems?

Should be accompanied by code! Codesandbox or Stackblitz provide a way to share code and discuss it in context

Details and Context

Vague question? Vague answer. Any details and context you can provide will lure more interesting answers!

Markdown supported.
Become a member to join the discussionEnroll Today