Add this code to $HOME/.zshrc
to automatically set the node version to match the version in package.json
.
# Add this code to .zshrc after nvm initialization code. | |
# | |
# Check the current directory for a package.json file | |
# If the node version is defined (at .engines.node) | |
# run "nvm use" for the node version. | |
# | |
# If there is not a node version defined with package.json, | |
# run "nvm use default" | |
# Version: 20230112 | |
# | |
# See https://salferrarello.com/automatic-switch-node-version-zsh-package-json | |
autoload -U add-zsh-hook | |
load-node-version-from-package-json() { | |
local package_json_path="$(pwd)/package.json"; | |
# Check if $package_json_path file exists. | |
if [ -f "$package_json_path" ]; then | |
local node_version="$(jq -r '.engines.node | select(.!=null)' $package_json_path)" | |
if [ "" = "$node_version" ]; then | |
echo "package.json has no .engines.node version defined"; | |
elif [[ $node_version == *"~"* ]] || [[ $node_version == *">"* ]] || [[ $node_version == *"^"* ]] then | |
echo "nvm does not support special characters (^, >, ~)"; | |
echo "No changes applied, please use nvm to set manually"; | |
echo "package.json .engines.node is $node_version"; | |
return 0; | |
else | |
echo "This directory has a package.json file with .engines.node ($node_version)"; | |
nvm use $node_version; | |
# Record modification of node version. | |
export NODE_VERSION_MODIFIED=true; | |
return 0; | |
fi | |
fi | |
if $NODE_VERSION_MODIFIED; then | |
# Revert to default node version. | |
echo "Reverting to default node version."; | |
nvm use default; | |
export NODE_VERSION_MODIFIED=false; | |
fi | |
} | |
add-zsh-hook chpwd load-node-version-from-package-json | |
load-node-version-from-package-json |
I work with a number of different packages that use different version of node and nvm is a life saver for managing this. The packages I work with define the node version in package.json
(under the property .engines.node
). I’ve previously written about Using jq and nvm to set the Node version. This code makes use of the zsh chpwd hook to automatically set the node version to the version specified in package.json
.
Dependencies
This code requires you have the following programs installed.
How It Works
First we define our function load-node-version-from-package-json()
, then we add the add-zsh-hook chpwd line, which uses a zsh hook to automatically run our function whenever “the current working directory is changed”.
Inside load-node-version-from-package-json()
we check for a package.json
file and extract the .engines.node
value using jq.
If the node version contains a special character (^
, >
, ~
) we warn the user and stop execution (nvm does not support versions with these characters).
If there is a node version, we use nvm to set the node version and set the variable NODE_VERSION_MODIFIED
to true
.
If we are unable to retrieve a usable node version from package.json
(or package.json
does not exist). We check if this window has modified the node version previously (by checking for the NODE_VERSION_MODIFIED
variable), if the node version was previously modified we use nvm to set it back to the default (nvm use default
) and set the variable NODE_VERSION_MODIFIED
to false
.
Similar Solutions
From .nvmrc
These automatically read the .nvmrc
file and set the node version.
- StackOverflow run
nvm use
automatically every time there’s a .nvmrc file on the directory - nvm Calling nvm use automatically in a directory with a .nvmrc file
Leave a Reply