Skip to content

Instantly share code, notes, and snippets.

@mcalthrop
Created June 10, 2022 13:56
Show Gist options
  • Save mcalthrop/95273691709df42986d31b8f956de5ca to your computer and use it in GitHub Desktop.
Save mcalthrop/95273691709df42986d31b8f956de5ca to your computer and use it in GitHub Desktop.
Managing the node version

Managing the node version

Defining the version of node used in a node-based repository can be a task that is overlooked.

What's the problem?

On a few occasions, I have come across a scenario similar to the following:

  • I am running a node-based application locally without any problems
  • a new developer joins the team, and tries to run it locally too
  • but they discover there is some obscure error occurs

After spending hours trying to find the cause of the issue, we finally discovered that the only difference beetween our developer setup was that our node versions were different, and only by a minor release.

It takes hours to discover, because it's probably one of the last things you'd expect – but it happens.

Another scenario:

  • one developer uses node v14.x is install packages initially
  • which uses npm v6.x, which generates a lock file using the version 1 lock file format
  • another developer is using node v16.x, and adds or updates a package
  • and that node version uses npm v8.x, which generates a lock file using the version 2 lock file format
  • the package-lock.json ends up having thousands of lines changed, but nobody notices
  • the first developer then has no idea what is going on when they get the latest code and run npm ci

The solution

To avoid misaligned node version pain, we need to ensure the following:

  • all developers are using the same version of node and npm
  • and the CI environment is also using that same version

For local development, there is more than one option; the one I have found most useful so far is nvm.

This not only specifies the node version, but also the npm version associated with it.

The simplest implementation is to add a .nvmrc file that contains the required node version – best to specify it to the patch level.

However, just adding this file does not enforce use of that node version, meaning that a developer still won't know if/when they are using the wrong version of node.

The enforcer

To make the environment setup more watertight, I have recently implemented a solution that checks the developer's node version at critical points in the development process, and won't allow the developer to continue if they have the wrong version.

It's not as light-weight as I would like, but once it is in place in one repository, it's easy enough to implement in other repos as well.

  • create a script that checks the node version in use against the version specified in .nvmrc
  • install husky to leverage git lifecycle hooks
  • add relevant git lifecycle hooks that run the script – I have found that the pre-commit, pre-merge, pre-push and pre-rebase hooks are the most useful

Some more detail

Create a shell script similar to this:

#!/bin/bash -eu

EXPECTED_NODE_VERSION=$(cat .nvmrc)
ACTUAL_NODE_VERSION=$(node --version)
if [[ ${ACTUAL_NODE_VERSION} != ${EXPECTED_NODE_VERSION} ]] ; then
  echo "ERROR: the version of node you are using is incorrect."
  echo "  You have: ${ACTUAL_NODE_VERSION}"
  echo "  You need: ${EXPECTED_NODE_VERSION}"
  echo "Please run 'nvm install' to fix this issue."
  echo
  exit 1
fi
echo "Node version: ${ACTUAL_NODE_VERSION}"

Add a scripts entry in your package.json file that calls your script:

"checkNodeVersion": "./check-node-version.sh"

Follow husky's Usage installation steps.

Use those instructions to call your script with npm run checkNodeVersion for the relevant git hooks.

Remember your CI configuration 🤩

Don't forget to specify the same version of node in your CI setup.

And run npm run checkNodeVersion as part of the CI tests.

And document it

It's a good idea to update the project's documentation to describe what to do when you want to change the node version 🤓

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment