Upgrading Node.js to Version 8

October 31, 2017 - by Wyatt Lyon Preul

Version 8 of Node.js begins its long term support (LTS) release plan today. This means that version 8 will remain stable as new features and regressions are less likely to be introduced. The only changes that are likely to occur are bug fixes, security updates, and other minor semantic version additions. As a result, now is the perfect time to begin upgrading your applications to run on version 8.

The following is a collection of recommendations on how to upgrade to Node.js version 8 and why you should. These recommendations are presented as a general tutorial to help guide you through the process of upgrading your applications. A similar tutorial was created last year to help guide you through upgrading from version 0.10 and 0.12 to version 4 and 6 of Node.js. If you haven't already upgraded from versions of Node.js prior to version 4 then please go back and read last years tutorial. Versions prior to 4 are no longer officially supported. As a result, unsupported versions of Node.js do not receive security or bug patches, leaving them vulnerable.

What's new in version 8

There are many new features and capabilities to be excited for in version 8. The following is a listing of some of the more prominent new features. The Node.js community maintains changelogs for each major release, therefore, there is a complete changelog for version 8 with all commits included.

  1. V8, the underlying JavaScript engine, has been updated to version 6.1. This includes numerous performance improvements and features.
  2. HTTP2 support is available in the module http2. Note that the npm module http2 will conflict with the internal http2 module name unless you set the environment variable NODE_NO_HTTP2.
  3. Async Hooks are available, which allow developers to register before/after handlers that execute around asynchronous operations. This is still an experimental feature and should not be used in production.
  4. N-API, a stable native addon API is now provided.
  5. Stable support for async/await operations.
  6. EcmaScript Modules support is available behind the --experimental-modules flag.
  7. fs.copyFile function now exists for copying files in a performant way.
  8. util.promisify function has been added to make it easier to move away from callbacks.
  9. util.callbackify to complement util.promisify.
  10. dns.Resolver class is added to make it easier to create multiple DNS resolvers.
  11. inspector module exists with support for creating V8 inspector sessions.
  12. 'perf_hooks` module added to make it easier take high resolution performance measurements.
  13. readable.destroy and writable.destroy are added to end/release resources on a stream and emit an error if one is provided.

Install the Node.js version manager

Install version 8 of Node.js and reinstall any global modules you had previously installed. Using the node version manager(nvm) is one of the simplest ways to accomplish this. If you are on Windows then you can use (nvm-windows)[https://github.com/coreybutler/nvm-windows]. Below is an example of using nvm to install version 8 and reinstall the modules from the 'default' aliased Node.js using nvm.

$ nvm i v8 --reinstall-packages-from=default
$ nvm alias default v8.

Assess tests

In all likelihood, an application with 100% code coverage from tests will be able to update Node.js versions with fewer production bugs. In other words, when you execute all of the code paths of an application, detecting bugs from a change in the underlying Node.js release will be more likely to happen in development. Therefore, if you have time and adequate resources, it's recommended to increase the code coverage.

Once you are confident in the application tests or your manual testing abilities, you can proceed by using the release of Node.js you plan to upgrade to, installing the latest dependencies, and running the tests. Below is an example of the commands to execute to perform these actions.

$ nvm use default           ## Use Node.js version 8
$ rm -rf node_modules/      ## Remove old dependencies
$ npm i                     ## Install latest dependencies using Node.js version 6
$ npm test                  ## Run tests

Hopefully, all of the tests pass and everything will work. Regardless of if all of the tests do pass, you should proceed by assessing your modules to ensure that they have support for the version of Node.js that you intend to use.

Assess 3rd party module support

Before changing anything in your application, you should review the 3rd party modules that are required by the application. Look through each module's registry entry and ensure that it supports the version 8 of Node.js. One way to determine if a module will work is to look at the engines property in the package.json file. The engines property isn't required to publish a module. Therefore, many modules in the npm registry are missing them. If that is the case, you can get a hint at what version of Node.js the module will work with by looking at the Node.js version that was used to publish the module. Below is a command that you can execute to print all of the Node.js versions used to publish the modules that are dependencies of the module in the current working directory.

$ curl -s $(npm info --json | json dependencies | json -ka | awk '{print "https://registry.npmjs.org/" $1}') -H "Accept: application/json" | json -ag versions | json -gMa -c "return this.value && this.value._nodeVersion" | json -ga value.name key value._nodeVersion

The above script assumes that you have json and curl installed. It prints the module name, version, and the version of Node.js that the module author used to publish the module.

Another method to determine if a module works on a particular Node.js version is to look at its Travis CI configuration. For example, the .travis.yml configuration file used across the hapi organization contains a node_js entry like the following, which indicate hapi works with both version 8 and the latest version of Node.js.

  - "8"
  - "node"

If a module doesn't work on version 8 of Node.js then you should be a good Open Source citizen and file an issue for the module author to assess. Before doing this, you should test the module against version 8 of Node.js. Below is an example of testing the hoek module. Similarly, other modules that you depend on should have a npm test script to execute.

$ git clone git@github.com:hapijs/hoek.git
Cloning into 'hoek'...
$ cd hoek && npm it

Review Node.js changes

At this point, the version of Node.js running in development should be the same version that you intend to use in production. Additionally, you ran the tests in your application against version 8 of Node.js. Finally, you reviewed any dependencies to check whether they will work with Node.js 8. Before altering any code in the application, you should consider the changes made to Node.js since the release of the one you are using in production. The Node.js community does an excellent job maintaining a list of major changes between versions.

Review the following changes, depending on the version of Node.js that you are upgrading from.

After consideration of the above lists of changes proceed by updating your application code to fix any issues caused by the above changes.

Update the application

Hopefully, the modifications you need to make to your application are trivial. Either way, try to avoid doing a massive refactor or using any new language features just yet. Instead, you should concentrate on getting the application into a stable state on the version of Node.js you picked to run in production.

Add engines Property

To indicate the version of Node.js that the application now supports add or update the engines entry in the package.json. Below is an example of an updated engines entry.

"engines": {
  "node": ">=8.0.0"

Next steps

At this point, you should have an updated version of your application working with version 8 of Node.js. The next step is to submit your changes and move the application through whatever pipeline your organization has chosen.

Congratulations and best wishes running the updated application in production!