Node.js Best Practices

Specify engines key in package.json

The first thing you should do is specify an engines key with your current version of node (node -v):

"engines": {
  "node": "7.6.0"
}

Use a smart .npmrc

By default, npm doesn’t save installed dependencies to package.json (and you should always track your dependencies!).

If you use the --save flag to auto-update package.json, npm installs the packages with a leading carat (^), putting your modules at risk of drifting to different versions. This is fine for module development, but not good for apps, where you want to keep consistent dependencies between all your environments.

One solution is installing packages like this:

npm install foobar --save --save-exact

Even better, you can set these options in ~/.npmrc to update your defaults:

$ npm config set save=true
$ npm config set save-exact=true
$ cat ~/.npmrc

Now, npm install foobar will automatically add foobar to package.json and your dependencies won’t drift between installs.

You can lock down your dependencies further with npm-shrinkwrap. However, note that the shrinkwrap workflow can be counterintuitive, and shrinkwrap has several known issues in older versions of npm.

Hop on the ES6 train

Node 4+ packs an updated V8 engine with several useful ES6 features. Don’t be intimidated by some of the more complex stuff, you can learn it as you go. There are plenty of simple improvements for immediate gratification:

let user = users.find(u => u.id === ID);

console.log(`Hello, ${ user.name }!`);

Stick with lower case

Some languages encourage filenames that match class names, like MyClass and MyClass.js. Don’t do that in Node. Instead, use lowercase files:

let MyClass = require('my-class');

Node.js is the rare example of a Linux-centric tool with great cross-platform support. While OSX and Windows will treat 'myclass.js’ and 'MyClass.js’ equivalently, Linux won’t. To write code that’s portable between platforms, you’ll need to exactly match require statements, including capitalization.

The easy way to get this right is to just stick with lowercase filenames for everything, eg my-class.js.

Cluster your app

Since the node runtime is limited to a single CPU core and about 1.5 GB of memory, deploying a non-clustered node app on a large server is a huge waste of resources. To take advantage of multiple cores and memory beyond 1.5 GB, bake Cluster support into your app. Even if you’re only running a single process on small hardware today, Cluster gives you easy flexibility for the future.

Testing is the best way to determine the ideal number of clustered processes for your app, but it’s good to start with the reasonable defaults offered by your platform, with a simple fallback, eg:

const CONCURRENCY = process.env.WEB_CONCURRENCY || 1;

Choose a Cluster abstraction to avoid reinventing the wheel of process management. If you’d like separate master and worker files, you can try forky. If you prefer a single entrypoint file and function, take a look at throng.

Be environmentally aware

Don’t litter your project with environment-specific config files! Instead, take advantage of environment variables.

First, install node-foreman:

Reference:

Best Practices for Node.js Development