npm Blog (Archive)

The npm blog has been discontinued.

Updates from the npm team are now published on the GitHub Blog and the GitHub Changelog.

Making your command line tool configurable

This is the third post in a tutorial on command line tools.

  1. Building a simple command line tool with npm
  2. Adding subcommands to your command line tool
  3. Making your command line tool configurable

Get the code.

In the first post, we used our command line tool to make it easy to share npm run scripts between projects. If these scripts are being used on different projects, though, you might need them to behave slightly differently.

For example, our github-pages commit command uses the same commit message (‘gh-pages update’) for every commit. It’s possible we’d want to specify this when we run the command. We also might want a different default commit message for a particular project.

In this post, you’ll see how you can add options to your subcommands so that their behavior can be configured. You’ll also see how you can set per-project defaults for these configuration options using config files.

Before we start

At the end of the last post, we were on version 2.0.0 of our module. We added a breaking change so we had to bump the first number to conform with semantic versioning.

This time, we’re going to be adding a new feature, not a breaking change. Because of this, we’ll bump the middle number to indicate that there’s a new feature in the release. While we’re working on it, we’ll use the alpha prerelease tag.

npm version 2.1.0-alpha.0

Step 1: Adding an option

  1. Declare the option with yargs

    You might have noticed before that we were passing the yargs object into the handler. We can use that object to declare the options for the command that this is the handler for.

    .command("commit", "commit changes to the repo", function (yargs) {
      var argv = yargs.reset()
        .option("m", {
          alias: "message",
          description: "Override the default commit message"
        })
        .help("h")
        .alias("h", "help")
        .argv
    
      shell.exec("git add -A . && git commit -a -m 'gh-pages update'");
    })
    

    When you run github-pages commit -h you’ll see the help message for the option.

    We don’t want to have to check for existence of the option, so be sure to have a default value for it.

  2. Use the option value

    The option will be available on the argv variable, so we can replace the previously hard-coded commit message with the variable.

    shell.exec("git add -A . && git commit -a -m '" + argv.message + "'");

Step 2: Handling configuration files

A config file makes it possible for you to set per-project default values for your command.

Add the config option name, which tells yargs what option will be used to pass in the config file.

var argv = yargs.reset()
  .config("config")
  ...

To make use of this in your project, you’ll add a config file:

  
  {
    "message": "this message comes from config"
  }
  

Then you’ll pass in the config file’s path when you use the command, github-pages commit --config=config.json.

If you’re looking for a more fully featured option for handling user configuration, take a look at the rc module.

Step 3: Update the module on npm

  1. Set a stable version number

    npm version patch
  2. Publish the module to npm

    If you’re publishing this as a private module, you can just run npm publish. If you’re publishing it as a public scoped module and this is your first time running the publish command, you will need to use the access option: --access=public.