Use nvm to Manage Multiple Versions of node.js
Have you ever been in a dilemma of upgrading your node.js
version or not? I have multiple node.js
projects I developed in the past using “latest” versions then, and I end up using node.js
v8, v10, v12 and v14. One solution I used in the past is to use Docker
, which works great. But managing those Docker
images and making them up to date is not an easy task, especially when I don’t do this often and what ends up happening is lots of research with try and error when I have to do it.
Today I discovered nvm
which solved my dilemma with a simpler workflow than using Docker
. nvm
allows me to install multiple versions
of node.js
independently and switch between them easily. It’s very similar to the concept of virtualenv
of python
if you have used it
before. But nvm
can’t create multiple environments like virtualenv
does, because it doesn’t need to. In thenode.js
world, your local package.json
is the virtual environment and all nvm
need to take care is the global packages and node.js
versions, which is exactly nvm
provides and the reason it’s so simple to use.
According to the documentation, brew
is not supported 😔. The recommended way to install is via curl
or wget
.1
2
3$curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
or
$wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
After this, you should see the additional configuration in your shell config file, in my case it’s .zshrc
1
2export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
Now nvm
is ready to be used! Everything will be in NVM_DIR
folder. nvm
provides a very neat deep integration with zsh
which allows automatic environment switch using a .nvmrc
file in a given directory. In order for this to work, put the following snippet to .zshrc
file1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21# place this after nvm initialization!
autoload -U add-zsh-hook
load-nvmrc() {
local node_version="$(nvm version)"
local nvmrc_path="$(nvm_find_nvmrc)"
if [ -n "$nvmrc_path" ]; then
local nvmrc_node_version=$(nvm version "$(cat "${nvmrc_path}")")
if [ "$nvmrc_node_version" = "N/A" ]; then
nvm install
elif [ "$nvmrc_node_version" != "$node_version" ]; then
nvm use
fi
elif [ "$node_version" != "$(nvm version default)" ]; then
echo "Reverting to nvm default version"
nvm use default
fi
}
add-zsh-hook chpwd load-nvmrc
load-nvmrc
Before installing node.js
versions I’d like, I want nvm
to install some default global npm
packages I always use, so I create a .nvm/default-packages
file and put the following npm
packages1
2
3
4
5
6hexo
@ionic/cli
firebase-tools
@angular/cli
generator-ngx-rocket
apify-cli
Now let’s try to install two versions I use which are lts/dubnium(v10.20.1) and lts/erbium(v12.16.3).1
2$nvm install lts/dubnium
$nvm install lts/erbium
After this, you should be able to switch between different versions using version numbers or alias. Let’s try it out the automatic way. I have a project with a .nvmrc
file and the content is lts/dubnium
. My default nvm
is configured to use lts/dubnium
. Now let’s see it in action.1
2
3
4
5
6$cd timeGarden
Found 'timeGarden/.nvmrc' with version <lts/dubnium>
Now using node v10.20.1 (npm v6.14.4)
$cd ..
Reverting to nvm default version
Now using node v12.16.3 (npm v6.14.4)
It’s working like a charm! Don’t forget to commit the .nvmrc
file so it will be a part of the project environment setup.
Reference: