When writing an application in Node.js it's best practice to lock down the version that you're using. This doesn't really happen out of the box and there are a few different things you can do to enable this and make it more manageable.
The following doesn't really apply when writing a reusable library you're going to publish on npm as you'll most likely want to be checking multiple Node.js versions.
Why do this?
First of all, it might not be clear why you'd want to fully lock this down. I've come across a few reasons why in my time:
- Node.js changes/deprecates APIs in major versions and sometimes introduces new APIs in minor versions so developers on different versions get inconsistent results
- npm and Yarn sometimes introduce new lockfile versions so a game of lockfile tennis starts where different developers on the team are changing it back and forth
- We should strive for parity with production
Use a version manager
The conventional way to manage versions in Node.js is through nvm. You add a .nvmrc
file stating the version used to the root of your repository and then you can quickly switch to that version. The content of the file is simply the version you want:
16.13.1
In your terminal when entering the directory of the project you can then do nvm use
(or nvm install
) and nvm will pick up the version and switch to it.
Add engines
to your package.json
You can also add your Node.js version to the engines
object in your package.json
.
"engines": {
"node": "16.13.1",
"npm": "^8"
},
Note how you can also enforce the npm version. I typically just set it approximately to the version that ships with the particular version of Node.js. You can also do the same with yarn
here too if that's what you're using.
Yarn
If in fact you're using Yarn (I prefer to) then any time you run a Yarn command it will make sure your local version of Node.js satisfies the constraint. If it's not a compatible version it will error and tell you why. This is great because the chance of making an error is vastly reduced.
npm
If you use npm
this will require a bit more work and not be as good. You'll need to set engine-strict
to true
in your .npmrc
file:
engine-strict = true
You should create this .npmrc
file in the root of the project and not put it in the one in your user directory so that it works for the whole team.
Adding this will make npm check during npm install
only. If you run anything else like npm start
or npm run dev
it will not check.
Maintenance
Now that you have versions specified you're a bit more protected from the mistakes and pitfalls of potentially having multiple versions in use mentioned earlier. If you're moving around to different projects during the course of your day you now have some protection from making these mistakes. You can simply do nvm use
and be placed on the relevant Node.js version for the project.
If you want to test a new version you can typically do a search for your existing version (16.13.1
for example) and update to the new version. You can then have your CI test that and deploy it to a test environment and get some confidence that you can upgrade successfully.
Going further with Docker and Dev Containers
Some teams will be using Docker so it makes it less likely that differing versions around the team happens. However, I still like to use the engines
feature in package.json
shown above as it gives that extra bit of protection and will probably be your last line of defence.
If the team are all using Visual Studio Code you could look at using Dev Containers. This ensures every developer has the same setup regardless of the platform they're using. They're also really helpful for onboarding new team members.
Top comments (0)