Here's how I do it, generally similar to Ross Shannon's answer, with a few differences:
- You can specify the Node version in just the
package.json
, without requiring an .nvmrc
file
- You can also specify the Node version directly in the
.envrc
, again without an .nvmrc
file
- I don't add
node_modules/.bin
to the PATH, but if that's your preferred behavior, just add PATH_add node_modules/.bin
to the use_nvm
function.
For me, supporting Node version selection from package.json
rather than .nvmrc
was important because I didn't want to worry about keeping two files in sync (especially on a project with multiple collaborators). That said, this solution still works with .nvmrc
.
This solution requires direnv, nvm and optionally (if you want to be able to select the Node version from package.json) jq.
In ~/.config/direnv/direnvrc
file, add the following:
# To use:
# 1) Node version specified in package.json, in .envrc add:
# use nvm package.json
# This requires that package.json contains something like
# "engines": {
# "node": ">=6.9.2"
# },
#
# 2) Node version specified in .envrc add:
# use nvm 6.9.2
#
# 3) Node version specified in .nvmrc, in .envrc add:
# use nvm
use_nvm() {
local node_version=$1
if [[ $node_version = "package.json" ]]; then
if has jq; then
node_version=$(jq --raw-output .engines.node package.json | tr -d "<=> ")
else
echo "Parsing package.json for node version to use with direnv requires jq"
fi
fi
nvm_sh=~/.nvm/nvm.sh
if [[ -e $nvm_sh ]]; then
source $nvm_sh
nvm use $node_version
fi
}
In your project directory, add an .envrc
file that calls use nvm
, e.g.:
use nvm package.json
However, I prefer something like the following for my .envrc
:
if declare -Ff use_nvm >/dev/null; then
use nvm package.json
fi
for shared projects with a shared .envrc
so that collaborators who don't have use nvm
defined don't get an error.
Now, when you enter your project directory, your desired Node version will be automatically used (the first time, you'll be prompted to whitelist your changes to .envrc
with direnv allow
).