Skip to content

Instantly share code, notes, and snippets.

@lrlna
Last active November 5, 2019 14:00
Show Gist options
  • Save lrlna/d1a2758fb7fff3e408cf80e20f0c0484 to your computer and use it in GitHub Desktop.
Save lrlna/d1a2758fb7fff3e408cf80e20f0c0484 to your computer and use it in GitHub Desktop.
creating a node.js cli

Setup

Create a directory where you want it, and run npm init.

Edit package.json to have a bin portion:

"bin": {
  "nori": "bin.js"
}

cat is what you will run in your command line, bin.js is where your code will live. You'd usually have a bin.js file if you have already an index.js handling your API or doing other stuff. If you just have the one file, calling it index.js is ok too.

In your bin.js add a line to let the system know this will be a bin file:

#! /usr/bin/env node

Then to double check that this all works, add a console.log for example:

#! /usr/bin/env node
console.log("butts")

And back in your terminal in your current file directory run: npm link. Now you can run your package anywhere on your system, it will just output your console.log:

✿ nori
butts

Parsing Arguments

There are like bigilion libraries that do argument parsing. I recommend: minimist -- great for literally everything that you might need to day to day, yargs -- great for something a bit more complex, comes with a bunch of tools that you might need. You can also just parse the arguments yourself:

DIY:

You parse arguments with just process.argv, and you will have to slice it as you go:

#! /usr/bin/env node
console.log(process.argv)

They return like this:

✿ nori --type cat --favourite-food tuna
[ '/Users/lrlna/.nvm/versions/node/v10.2.1/bin/node',
  '/Users/lrlna/.nvm/versions/node/v10.2.1/bin/nori',
  '--type',
  'cat',
  '--favourite-food',
  'tuna' ]

So to get rid of the first two and get your actual arguments:

#! /usr/bin/env node

var argv = process.argv.slice(2)
console.log(argv) // [ 'cat', '--favourite-food', 'tuna' ]
// do what you need to do with the args

Minimist

npm i -S minimist to save to your package.json. and then add it to your bin.js

var argv = require('minimist')(process.argv.slice(2));
console.log(argv)

This will return a really nice object you can then get stuff out of:

✿ nori --type cat --food tuna
{ _: [], type: 'cat', food: 'tuna' }

So you can then right your if/else statements based on the type of arguments you get:

#! /usr/bin/env node

var argv = require('minimist')(process.argv.slice(2));

if (argv.type) {
  console.log('ofc she is a cat')
}
if (argv.food) {
  console.log('ofc she likes tuna')
}

Which would give you something like this when you run:

✿ nori --type cat
ofc she is a cat
✿ nori --food tuna
ofc she likes tuna
@jazlalli
Copy link

jazlalli commented Nov 5, 2019

Edit package.json to have a bin portion:

TIL! There I was messing about with symlinks and permissions myself when this is much simpler.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment