28

7 libraries to build Node.js CLI

 4 years ago
source link: https://dev.to/yvonnickfrin/7-libraries-to-build-node-js-cli-3jc7
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Last week, I wrote an article about building a Node.js CLI using yargs . I introduced it saying we use cli tools everyday to simplify common tasks in our jobs. I made myself a couple of cli like gitmoji-changelog . It is a changelog generator for gitmoji commit convention.

I would like to share with you a few libraries I used on this project and while contributing to Gatsby . Gatsby is a good source of inspiration, consider contributing to it. I learned a lot while doing it (they give free swag to thank contributions ).

yargs

:link: repository

It is a library that helps you defining your tool's interface. It also parses arguments for you. The icing on the cake is that yargs generates automatically an help menu.

Here is a simple example that displays a message "Hello [something]" a certain amount of times.

require('yargs')
  .command('$0 [name]', 'say hello', (yargs) => {
    yargs
      .positional('name', {
        describe: 'hello\'s target',
        default: 'world'
      })
      .option('times', {
        alias: 't',
        type: 'number',
        default: 1,
        description: 'number of times to say hello'
      })
  }, (argv) => {
    for (let i = 0;i < argv.times; i++) {
      console.log(`Hello ${argv.name}!`)
    }
  })
  .argv

Result:

2aqeiu7.gif

prompts

:link: repository

A common use case in cli tools is asking user for information. Prompts is a lightweight library based on promises. It implements an exhautive list of question's types.

(async () => {
  const prompts = require('prompts')

  const response = await prompts({
    type: 'confirm',
    name: 'value',
    message: 'Can you confirm?',
    initial: true
  })

  console.log('Reponse: ', response.value)
})()

Result:

Mj6jMjI.gif

signale

:link: repository

Standard console API provides only a few methods to display information. Signale comes with 19 built-in methods (logs are prefixed with emojies :heart:)! You can also implements custom loggers.

const signale = require('signale')

signale.success('CLI started');

const options = {
  types: {
    santa: {
      badge: ':alien:',
      color: 'magenta',
      label: 'alien',
      logLevel: 'info'
    }
  }
}

const custom = new signale.Signale(options);

custom.santa('E.T go home')

signale.complete('Call sent')

Result:

AnUBRj2.gif

chalk

:link: repository

It is a pain in the neck to add style to a cli output. Chalk provides an easy-to-use API to colorize logs. It also supports template literals!

const chalk = require('chalk')

console.log(`${chalk.blue('Welcome')} in the activity monitor${chalk.red('!')}`)

console.log(chalk.green(`Your computer seems in ${chalk.underline('great')} shape.`))

console.log(`
envinfo:
CPU: ${chalk.red('90%')}
RAM: ${chalk.green('40%')}
DISK: ${chalk.yellow('70%')}
`)

Result:

meMVVf2.gif

progress

:link: repository

Another common use case is dealing with asynchronous operations. It is nice to give user a percentage of completion when your cli is doing a heavy computation. Progress is an highly customizable ascii progress bar. It comes with a bunch of options and standard information (percentage, total, estimated completion, ...) to display on the progress bar. You can also add your own information.

const ProgressBar = require('progress')

let ticks = 0

const bar = new ProgressBar(
  'Rocket launch :bar in :counter',
  { total: 10, width: 50 },
)

const timer = setInterval(function () {
  ticks++
  bar.tick({ counter: 10 - ticks })
  if (bar.complete) {
    console.log('\n:rocket:')
    clearInterval(timer)
  }
}, 100)

Result:

VZBVfq6.gif

configstore

:link: repository

Earlier we saw Prompts to ask user information. It is also nice to store its answer to avoid asking it again and again. Configstore is a library that persists data for you. It stores it in a json file on the user's disk. It handles well the dot notation!

const Configstore = require('configstore')
const packageJson = require('../package.json')

const config = new Configstore(packageJson.name)

config.set('answer', true);
console.log('answer:', config.get('answer'));

config.set('a.really.deep.config', true);
console.log('a.really.deep.config:', config.get('a.really.deep.config'));

config.delete('answer');
console.log('answer:', config.get('answer'));

Result:

im6fYva.gif

envinfo

:link: repository

As frontend developer I use user-agent to get information about my user device. It helps a lot to reproduce bugs for example. As cli developer you don't have access to this kind of information. envinfo is a library that generates reports that users can provide when opening issues on your project.

(async () => {
  const envinfo = require('envinfo')

  const environment = await envinfo.run(
    {
      System: ['OS', 'Shell'],
      Binaries: ['Node', 'Yarn', 'npm'],
      Utilities: ['Git'],
    },
    { markdown: true }
  )

  console.log(environment)
})()

Result:

EZRJfir.gif

Alternatives exist for these libraries but I used these ones and I enjoy working with them. In my opinion, they covers the majority of problems you might encounter while coding cli tools.

Hope it will help :raised_hands: Happy cli coding!

Feedback is appreciated :pray: Please tweet me if you have any questions @YvonnickFrin !


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK