NPM Package Manager

NPM package manager plays an important role in Node.js ecosystem. Every serious Javascript developers should learn how to create a package with npm. In this post, I am going to cover several important npm commands.

Initialize a NPM Package

To start a project, we have to create package.json to describe the package and its dependencies. We can do so by running npm init. Here are the instructions:

First, create a directory to hold the package:

$ mkdir hello_express
$ cd hello_express

Second, run npm init to create package.json:

$ npm init
name: (hello_express)
version: (1.0.0)
description: Express.js example project
entry point: (app.js)
test command:
git repository:
keywords:
author: John Smith <john.smith@example.com>
license: (ISC) MIT
About to write to /path/to/your/project/hello/package.json:
# ... output skipped ...
Is this ok? (yes)

This command will ask several questions. After filling the answers, it will create package.json with the package information.

Now, we can continue to add dependencies with npm install.

Add Dependencies

Before adding dependencies to the package, we have to know the classification of the dependencies. NPM classifies the dependencies in three categories:

  • Production -- Production dependencies should be installed in the production environment. These are essential to a package. A package won't work without these dependencies. For example, most web application will list express as a production dependency, which should be installed on the web server.
  • Optional -- Like production dependencies, optional dependencies will be installed in the production environment. However, a package should be able to work without optional dependencies or at least degrade gracefully. For example, chokidar, a popular file monitoring package, is listing fsevent as an optional dependency, which provides better support on Mac OS X.
  • Development -- Development dependencies are for developers only. This includes tools to compile assets, run unit tests, etc. For example, nodemon is a file monitor daemon which will automatically reload Express applications when source files are modified. It is clear that nodemon is only meaningful to developers, thus nodemon should be listed as a development dependency.

After knowing the classification, we can continue on the command line usages.

First, use --save option to add a dependency for production environment. For example, we can install Express web framework with:

$ npm install --save express

Second, use --save-optional option to add an optional dependency for production environment. For example, we can install cookie-parser as an optional dependency.

$ npm install --save-optional cookie-parser

Third, use --save-dev option to add a dependency for development environment. For example, we can install nodemon with:

$ npm install --save-dev nodemon

Write Code

To complete the picture, let's write some code for our example package. The following code snippet is extracted from app.js:

'use strict';

var express = require('express'),
    app = express(),
    cookieParser = null;

try {
  cookieParser = require('cookie-parser');
} catch (e) {
  /* Ignore exception thrown by require(). */
}

if (cookieParser) {
  app.use(cookieParser());
}

app.get('/', function (req, res) {
  var visited;
  if (!cookieParser) {
    res.send('Hello world!');
    return;
  }
  if (req.cookies.visited === '1') {
    res.send('Hello, nice to meet you again!');
  } else {
    res.cookie('visited', '1');
    res.send('Hello, new visitor!');
  }
});

var server = app.listen(3000, function () {
  var addr = server.address();
  console.log('Listening at %s:%s', addr.address, addr.port);
});

As you can see, we are importing express as a mandatory dependency. On the other hand, cookie-parser is treated as an optional dependency. app.js will degrade gracefully without cookie-parser.

Finally, we can run nodemon to test our application:

$ nodemon app.js
[nodemon] 1.9.1
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `node app.js`
Listening at :::3000

Let's open the browser and say hello to our example application!

Install Packages

So far, we have only discussed the situation that we are creating a new NPM package. How do we install the dependencies when have the source code of an existing package? Imagine that we have cloned the Git repository of a package and we would like to install the dependencies specified in package.json.

The answer is simple: run npm install to get every dependencies. These includes production, optional, and development dependencies.

$ npm install

If you don't want the development dependencies, then specify --only=prod.

$ npm install --only=prod

If you don't want the optional dependencies, then specify --no-optional:

$ npm install --no-optional

If you want neither production nor optional dependencies, then specify --only=dev:

$ npm install --only=dev

Epilogue

We have gone through the essential steps to create package.json and specify the dependencies for a package. In addition, we have explained the classification of dependencies. Hope you enjoy this post. Let's create NPM packages together!