What is a Yargs

Yargs is a great command-line library that, in short, makes the process of creating an application to run in the console a breeze. What else could make it better? It’s pirate-themed (its name is YARgs), making it officially the best tool of all time.

You probably know that other CLI, such as vue-CLI, can easily set up a vue.js project or create-react-app, so the concept should be familiar to most people.

start

mkdir yargs_practice
cd yargs_practice
touch yargs.js
Copy the code

Initialize the project and install yargs

npm init -y
npm i yargs
Copy the code

Package. json looks like this:

{
  "name": "yargs_practice"."version": "1.0.0"."description": ""."main": "yargs.js"."scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": []."author": ""."license": "ISC"."dependencies": {
    "yargs": "^ 15.3.1"}}Copy the code

Use vscode to open the current directory

code .
Copy the code

Edit yargs. Js

const yargs = require("yargs");
const argv = yargs.argv;
console.log(argv);
Copy the code

Running in a terminal

node yargs.js add --new thing --old="stuff"
Copy the code

The result is as follows

Yard can easily get command line parameters

Continue to modify yargs.js

const yargs = require("yargs");
const argv = yargs
  .command("add"."Add a new note")
  .command("list"."List all notes")
  .help().argv;
Copy the code
  • commandYou can add command line information
  • helpMethod to display help information

Running in a terminal

node yargs.js --help
Copy the code

The following information is displayed:

Yargs provides shortcut command methods (aliases) to make some commands more concise

Continue to modify yargs.js

const yargs = require("yargs");
const argv = yargs
  .command("add"."Add a new note")
  .command("list"."List all notes")
  .help()
  .alias("help"."h").argv;
Copy the code

Running in a terminal

node yargs.js -h
Copy the code

You get the same result as –help

TODO:: Option

const yargs = require("yargs");
const argv = yargs
  .command("add"."Add a new note")
  .command("list"."List all notes")
  .help()
  .alias("help"."h").argv;
Copy the code

Yargs also supports the following subcommands

const yargs = require("yargs");
const argv = yargs
  .command("add"."Add a new note", {
    title: {
      describe: "Title of note".alias: "t".demandOption: true,},body: {
      describe: "Body of note".alias: "b".demandOption: true,
    },
  })
  .command("list"."List all notes")
  .help()
  .option("find")
  .alias("help"."h").argv;
Copy the code

Added subcommand title to add command

  • describeIs the description of this command
  • aliasIs shorthand for this command
  • demandOptionsaidtitleYou have to pass parameters

When we execute in the terminal

node yargs.js add -h
Copy the code

Note that this is different from node yargs.js -h, which shows the help information for the add command

The instance

Let’s look at a little example of how yargs can be used. Okay

We need to make some adjustments to the package.json file because we are creating a CLI. That’s what it looks like right now.

{
  "name": "yargs_practice"."version": "1.0.0"."description": ""."main": "yargs.js"."scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "bin": {
    "line-count": "./line-count"
  },
  "keywords": ["cli"]."preferGlobal": true."author": ""."license": "ISC"."dependencies": {
    "yargs": "^ 15.3.1"}}Copy the code

Here are the important changes to be aware of.

We add a bin value, which maps the entry file we create later to its executable file name (you can set it to whatever name you want we’ve set preferGlobal to true, This means that our packages want to be installed globally (for example via NPM install -g). Other tweaks include changing descriptions, deleting scripts already in use, adding author names, and so on.

Create a basic CLI

Yargs makes parsing command-line arguments very easy, and many example projects can be found here.

We’ll create a basic CLI that accepts a file as an argument and counts its lines.

To do this, first create a main script file.

touch line-count
Copy the code

Edit this file

#! /usr/bin/env node
const argv = require("yargs")
  .usage("Usage: $0 <command> [options]")
  .help("h")
  .alias("h"."help").argv;
Copy the code

Let’s go through all the code line by line.

  1. #! /usr/bin/env nodeIs an instance of a shebang line that tells our system what interpreter to use to execute the file
  2. .usage('Usage: $0 <command> [options]')Sets the CLI usage information that will be displayed when the –help command is called.
  3. .help('h')Bind help commands to optionshOn.
  4. .alias('h', 'help')For the options-hAn alias is created, i.e--help.

As you can see, this first step is very simple and yargs syntax is intuitive.

Next we will add the count command.

Simply add the following lines to the CLI you already have.

.command("count"."Count the lines in a file")
.example("$0 count -f foo.js"."count the lines in the given file")
Copy the code

Look line by line:

  1. .command(“count”, “count the lines in a file”) creates a new command named count and sets a description.

  2. .example(“$0 count -f foo.js”, “count the lines in the given file”) creates an example with a description that will be displayed when the user calls the –help option or when they forget the command.

This is all well and good, but running the node line-count count doesn’t do much good right now. Next we need a filename to complete the CLI by counting and displaying the number of lines.

Add the following information

.alias("f"."file")
.nargs("f".1)
.describe("f"."Load a file")
.demandOption(["f"])
Copy the code

Line-count should end up like this.

#! /usr/bin/env node
const argv = require("yargs")
  .usage("Usage: $0 <command> [options]")
  .command("count"."Count the lines in a file")
  .example("$0 count -f foo.js"."count the lines in the given file")
  .alias("f"."file")
  .nargs("f".1)
  .describe("f"."Load a file")
  .demandOption(["f"])
  .help("h")
  .alias("h"."help").argv;
Copy the code

Line by line, explain the newly added code

  1. Alias (“f”, “file”) creates an alias –file for the -f option.

  2. Nargs (“f”, 1) Sets a parameter (filename) for this option, otherwise the –help menu is displayed.

  3. .description(“f”, “Load a file”) adds a description to this option.

  4. .demandOption([[“f”]), because we need a filename, we require the -f option.

Finally, let’s add the logic of the program.

// Create stream with the file
const s = fs.createReadStream(argv.file);

var lines = 0;
s.on("data", (buf) => {
  // Get the number of lines
  lines += buf.toString().match(/\n/g).length;
});

s.on("end", () = > {// Display the number of lines
  console.log(lines);
});
Copy the code

That’s it. Let’s try it.

So far, our program has been running like this, but if we call it directly, we get an error.

We can solve this problem by globally registering the binaries (which we previously defined as bin in package.json) using the NPM link command.

Execute in the current directory

npm link
Copy the code

Congratulations 🎉, you can now run your scripts locally like this.

line-count count -f package.json
Copy the code

Publish CLI to NPM

Before deployment, we need to add some information to package.json.

"homepage": "YOUR GITHUB REPO OR SITE HERE",
"repository": {
  "type": "git",
  "url": "git+YOUR GITHUB REPOSITORY HERE"
},
"engines": {
  "node": ">=8"
},
Copy the code
  • Enter your own GitHub project address for homepage and Repository
  • Engines to confirmnodejsA version number, which simply defines the node on which your project should work in the smallest version. The version number depends on which version features you use.

Here are the next steps.

  • innpmjs.comCreate an account on (optional, ignore if there is one)
  • runnpm loginCommand and enter your information
  • runnpm publishCommand, which will be published automatically in a few minutes.

That’s it! If you want to update your project in the future, you need to change its version number in the package.json file and run the publish command again.

reference

  1. Building a CLI with Yargs
  2. How to use Yargs