It’s not uncommon to have to manage multiple versions of Node.js on one development machine. This challenge is exacerbated when the developer is having to maintenance multiple websites, some of which may be quite old and making use of older versions of Node.js and Node global tooling modules. It may not be appropriate to update the project to the latest/greatest versions of modules because of breaking changes and limited time for refactoring. Just as common is the situation where a developer may wish to experiment with a newer version of Node.js or a different version of a global module without disrupting their development environment.
NVM to the Rescue
One way to simplify the management of multiple versions of Node.js is via a tool called Node Version Manager (NVM) on Unix-based systems and NVM for Windows on Windows-based systems. NVM (for Unix) is a creative set of bash scripts which ensure the specified version of Node.js is the one used in a given shell environment. The Windows version is similar in functionality and an equally clever endeavor which is implemented in Go and uses symbolic links to facilitate pointing the normal Node.js installation location to a different actual location. Follow the previous links for information for how to install each.
NVM permits installing and use multiple versions of Node.js on a development system without having to continuously uninstall and re-install. This ease-of-use is helpful when trying out new versions of Node as well as different versions of globally available modules (like Angular or React). One feature of NVM is that it keeps separate locations for each Node.js version’s global modules. That is, when you switch versions of Node.js you get a unique global node_modules directory. This uniqueness allows you to install different versions of global tools to coincide with a Node.js version. This facilitates easy switching between older projects using older Node modules which may require older global modules with which they were originally built. This feature only applies to the global modules as individual project’s node_modules directories behave the normal way.
It can be helpful to have a script with each project that specifies both the version of node the project expects as well as the global modules it may needs. For example, a bash script named “install-required-tools.sh” could be added to the top-level of a project and might look like this:
#!/bin/bash nvm install 10.0.3 nvm use 10.0.3 npm install -g @email@example.com npm install -g firstname.lastname@example.org npm install -g email@example.com # Install other local project modules npm install
On Windows, the “nvm use 10.0.3” may require a mouse-click confirmation if the version of Node.js isn’t already active. No manual confirmation is needed on Unix, which makes it much easier for automated builds. Also, in Unix, you can work with different versions of node simultaneously in different terminals sessions. Not so much in Windows, but nvm still makes it easier to switch back and forth. The script above only need be run when someone changes it (e.g., to bump the version of Angular.)
The added benefit of such a script is that it means the project no longer need to document a list of commands to run or things to install globally in a README.md or project wiki. It need only document, “run this script”. Such an update is easy to communicate to a team, “Hey guys! Run the install-required-tools.sh script when you pull the latest!”.
There are limitations to this approach. If you need one version of node in conjunction with multiple versions of global tools it may become more difficult. In such a case I might begin to suggest the user of Docker or a VM for your development environment.