This article discusses best practices for Node.js, including the Node.js code style and developer workflow.

Code style.

The callback contract

Modules should expose error-first callback interfaces.

module.exports = function (dragonName, callback) {  
  // do some stuff here
  var dragon = createDragon(dragonName);

  // note, that the first parameter is the error
  // which is null here
  // but if an error occurs, then a new Error
  // should be passed here
  return callback(null, dragon);
}
Copy the code

Always check for errors in callbacks: To understand this, let’s start with an example of a violation of this rule

// this example is **BROKEN**, we will fix it soon :)
var fs = require('fs');

function readJSON(filePath, callback) {  
  fs.readFile(filePath, function(err, data) {  
    callback(JSON.parse(data));
  });
}

readJSON('./package.json', function (err, pkg) { ... }
Copy the code

The main problem with the readJSON function is that it does not check for an Error if it occurs during execution.

The improved version is as follows:

// this example is **STILL BROKEN**, we are fixing it! function readJSON(filePath, callback) { fs.readFile(filePath, function(err, data) { // here we check, if an error happened if (err) { // yep, pass the error to the callback // remember: error-first callbacks callback(err); } // no error, pass a null and the JSON callback(null, JSON.parse(data)); }); } ** returns in a callback! **Copy the code

The problem with the code above is that when an Error occurs, execution of the program does not stop in the if statement, but continues. This leads to a lot of unexpected problems. As mentioned in bold above, always return in a callback!

// this example is **STILL BROKEN**, we are fixing it! function readJSON(filePath, callback) { fs.readFile(filePath, function(err, data) { if (err) { return callback(err); } return callback(null, JSON.parse(data)); }); } ** Use try-catch** only in synchronized codeCopy the code

One thing to note is that json. parse throws an exception if it cannot format the specified string into JSON format.

Since json.parse is a synchronization function, we can wrap it in a try-catch block. It is important to note that try-catches can only be used in synchronized blocks of code, you cannot use them in callbacks!

// this example **WORKS**! :)
function readJSON(filePath, callback) {  
  fs.readFile(filePath, function(err, data) {
    var parsedJson;

    // Handle error
    if (err) {
       return callback(err);
    }

    // Parse JSON
    try {
      parsedJson = JSON.parse(data);
    } catch (exception) {
      return callback(exception);
    }

    // Everything is ok
    return callback(null, parsedJson);
  });
}
Copy the code

Avoid this and new

Binding to the specified context in Node is not always a good idea, as passing callback functions are often involved in Node programs and high-level functions are often used to manage workflow. A functional style of programming will save you a lot of trouble.

Creating small modules

Using Unix:

Developers should build a program out of simple parts connected by well defined interfaces, so problems are local, and parts of the program can be replaced in future versions to support new features.

Keep modules small enough (cohesive) that modules should only do one thing!

Use good synchronization mode

Using async

Error handling

Errors fall into two main categories: Operational errors and programmer errors.

Operational errors

Such as:

  1. The request timeout
  2. Insufficient system memory
  3. Failed to connect to the remote service

To deal with the Operational errors

Log everything! Enable the logging service!

Programmer error

A programmer error is a bug in a program. This is something you can try to avoid, like:

  1. Callbacks are not used when calling asynchronous methods
  2. Unable to readundefinedThe properties of the

Workflow Recommendations

usenpm initStart a new project

The init command creates a package.json file for your application and sets some initial values that you can modify later. Try starting a new project with this command:

mkdir my-awesome-new-project  
cd my-awesome-new-project  
npm init
Copy the code

Specify a start and test script

In package.json you can set the script using the script property. By default, NPM init generates two, start and test. You can execute them using NPM start and NPM test.

Of course, you can also define your own script, using the following command to run NPM run-script.

Note that NPM sets $PATH to find the executable in node_modules/.bin. This avoids installing the global NPM module. That is, with tools like Grunt, you can install the NPM module only in the project, rather than globally.

The environment variable

Different environment variables may need to be set up in production and development environments. The most common method is to set up production or staging, respectively, via NODE_ENV.

You can load different configuration information based on different environment variables, for example with the help of the Nconf module.

Of course, you can also use process.env to use other environment variables in your Node.js application, that is, you can include the user environment in an object.

Refer to the Node documentation.

Don’t reinvent the wheel

Start by looking for existing solutions. NPM includes a wealth of packages, so make the most of them.

Use style Guide

Refer to RisingStack’s Node.js style guide.

References

  1. This article translated from: https://blog.risingstack.com/node-js-best-practices/