Tag Archives: NodeJS

How To Create NodeJS CLI Module And Published To NPM

I recently published my first public NodeJS module a couple months ago. It wasn’t my first CLI module but the first time I published something to NPM repository. I figured it would be a good idea to document and share the process.

The module I created is based on a command line script I put together a while back to scratch an itch I had with JSON files. I deal with JSON files a lot and most times they’re minified. There are a bunch of tools to prettify JSON but most of them are web based or in text editors. To avoid having to copy/paste JSON between screens I started searching for CLI scripts. Most of the ones I found either did too much or too little. I wanted a simple tool to prettify or minify JSON. So I wrote one called pretty-mini-json.

The code used to prettify and minify JSON was extremely simple. NodeJS has a built in JSON parser conveniently called JSON. It can be used to parse JSON strings into a proper JSON object and convert them back into strings. The JSON.stringify() function is used to convert them back but it can also generate a pretty or minified version. That’s all I needed at the core of this script. The rest is exposing this to the CLI, making it a proper NodeJS module and publishing it to NPM repository.

Create NodeJS Command Line Interface
The first thing I had to include in my script to make it command line friendly was the shebang line.

#!/usr/bin/env node

If your not familiar with the shebang and how it’s used then check out the wiki page.

Next I needed to parse the arguments passed into my script. This can be done from scratch by parsing process.argv. If your tool is simple then I recommend that route. But I wanted to add a number of options to my script so I choose to use an existing module to help parse arguments and make it easy to present those options. A module called commander fit perfectly.

So I added commander to my package.json file (more on that in a bit). Then added the module to my script using this line…

var program = require("commander");

Now I can chain together the way I want to parse the arguments using the commender object I stored as program.

program
    .version(pkgJSON.version)
    .usage("[options] [file ...]")
    .description("A simple CLI tool to shrink/minify or prettify JSON data.")
    .option("-p, --pretty", "prettify JSON data", "true")
    .option(
        "-o, --outputFile ",
        "write output to  instead of stdout"
    )
    .option(
        "-v, --verbose",
        "makes stdout more verbose/talkative. Mostly useful for debugging.",
        "true"
    )
    .parse(process.argv);

I won’t go into all of the functions available via the commander object. The main two to focus on for now are the option() and parse() functions. If you want to learn more about commander then check out the module readme.

The option() function is pretty straight forward. It defines all the options your script will process. The first argument defines the option letter and name. Second argument is the description and the third is the default value.

The last function called is parse() which is also straight forward. It will parse the process.argv and store the results in the program object using the option names defined in the option() function calls.

Now I can use the stored option values to return either prettified or minified JSON data. The only other CLI related bit that’s in the module is the standard input check and event handlers. I use those to check if there was any standard data stream passed into the script, collect the data and then process it. NodeJS provides the process.stdin for this. I also don’t output any logging data via console.log since many CLI users want to pipe the output of one script to another or some other process. For debugging I added the -v or --verbose option if user wants logs displayed.

That’s it! Now the script is CLI ready. Next I need to wrap this up into a package and publish to NPM repo.

Create NPM Package
NPM is included in the NodeJS install. You can update it separately by running sudo npm install npm -g. It started out as the Node Package Manager but now it’s used for many types of JavaScript packages. But I’m gonna create a traditional NodeJS package. The first thing I need to do is create a package.json file.

You can create the package.json file manually or via the npm init command. I prefer to do it manually in my text editor. Make sure the file is created in the directory that contains your NodeJS module. Typically this directory would have the same name as your module. The package.json file only requires two fields…

{
    "name": "pretty-mini-json",
    "version": "1.0.0"
}

Both are pretty straight forward. Keep in mind that name value should be the same as the parent directory and the version value should be based on semantic versioning. This is all that’s required but I had some more fields I wanted to use since this would be published to NPM repo.

{
  "name": "pretty-mini-json",
  "description": "A simple CLI tool to shrink/minify or prettify JSON data.",
  "keywords": [
    "cli",
    "util",
    "json",
    "minify",
    "shrink",
    "pretty",
    "prettify",
    "pipe",
    "stdout",
    "stdin"
  ],
  "author": "Mode54 <info@mode54.com> (http://Mode54.com)",
  "repository": {
    "type": "git",
    "url": "git://github.com/Mode54/pretty-mini-json.git"
  },
  "bugs": {
    "url": "https://github.com/Mode54/pretty-mini-json/issues"
  },
  "main": "./pretty-mini-json.js",
  "version": "1.0.0",
  "dependencies": {
    "commander": "2.8.x"
  },
  "license": "MIT",
  "bin": {
    "pretty-mini-json": "pretty-mini-json.js",
    "pmj": "pretty-mini-json.js"
  }
}

I won’t go into each field. You can checkout this handy interactive guide to find out what each field is for. The two I want to point out are the dependencies field which includes any modules the script will depend on (in my case the commander module) and the bin field which contains binary scripts to expose to the CLI. I’m using the bin field as a way to create a couple aliases to the same script.

Now I’m ready to publish this bad boy to the public NPM repo!

Publish NodeJS Package To NPM
I need to register with NPM in order to publish to the repository. This can be done online using the sign up form but I just did it from the CLI since I’d have to run the same command either way.

npm adduser

I enter my username, password and email (this email will be visible to the public). Then check to make sure I have an account created on the NPM repo by going to https://www.npmjs.com/~mode54. Replace mode54 with your own user name. Also made sure user info was stored locally by running this CLI command:

npm config ls

Once the user info is set then I can run the publish command to send my package up to NPM repository

npm publish

Yay!! My first NodeJS CLI script published to NPM!!