nvmでNode.jsのバージョンを自動切替
emmdee@colus.img
プロジェクトごとにバージョンを固定する
そのプロジェクトで使用するNode.jsのバージョン番号だけを書いたテキストファイルを.nvmrc
という名前でプロジェクトルートに置く。
10.15.1
プロジェクトのディレクトリ内で$ nvm use
と打つと階層を上にたどって.nvmrcファイルを見つけ出し、そのバージョンに切り替えてくれる。
これだけでも十分便利だが、意外とコマンドを打つのを忘れることが多い。
バージョンを自動で切り替える
nvm公式のGitHubページに「Deeper Shell Integration」というシェルスクリプトが紹介されている。.bashrc
に追記すると、cd
でディレクトリを移動するたびに.nvmrcファイルを探し、バージョンを自動で切り替えてくれるというものだ。
早速、bash版のシェルスクリプトを使ってみた。しかし、cd
するとエラーでシェルが終了してしまう。環境依存のレアケースなのか、検索してもそれらしい答えは見つからなかったが、下記ページにヒントがあった。
cdの前にバックスラッシュを入れないとaliasで呼び出した時に無限ループをするので、必ずバックスラッシュ を付けてください
ということで、公式シェルスクリプトBash版の10行目、cd "$@";
を\cd "$@";
と修正すると無事動作した。
起動時にも動作させる
このスクリプトはcd
コマンドでのディレクトリ移動に伴ってバージョンを自動で切り替える動作を行うものだ。そのため、VS Codeのターミナルのように最初からプロジェクトルートで起動する場合は、起動後にcd
コマンドを使わないため動作しない。
そこで、このスクリプトからcd以外の部分を切り出し、ターミナルの起動時にも自動でバージョンを変更するよう修正した。
下記がその修正版。
これでストレスなくプロジェクトごとにnodeのバージョンが自動で切り替わるようになった。
find-up () {
path=$(pwd)
while [[ "$path" != "" && ! -e "$path/$1" ]]; do
path=${path%/*}
done
echo "$path"
}
nvmuse(){ nvm_path=$(find-up .nvmrc | tr -d '[:space:]') # If there are no .nvmrc file, use the default nvm version if [[ ! $nvm_path = *[^[:space:]]* ]]; then declare default_version; default_version=$(nvm version default); # If there is no default version, set it to `node` # This will use the latest version on your machine if [[ $default_version == "N/A" ]]; then nvm alias default node; default_version=$(nvm version default); fi # If the current version is not the default version, set it to use the default version if [[ $(nvm current) != "$default_version" ]]; then nvm use default; fi elif [[ -s $nvm_path/.nvmrc && -r $nvm_path/.nvmrc ]]; then declare nvm_version nvm_version=$(<"$nvm_path"/.nvmrc) declare locally_resolved_nvm_version # `nvm ls` will check all locally-available versions # If there are multiple matching versions, take the latest one # Remove the `->` and `*` characters and spaces # `locally_resolved_nvm_version` will be `N/A` if no local versions are found locally_resolved_nvm_version=$(nvm ls --no-colors "$nvm_version" | tail -1 | tr -d '\->*' | tr -d '[:space:]') # If it is not already installed, install it # `nvm install` will implicitly use the newly-installed version if [[ "$locally_resolved_nvm_version" == "N/A" ]]; then nvm install "$nvm_version"; elif [[ $(nvm current) != "$locally_resolved_nvm_version" ]]; then nvm use "$nvm_version"; fi fi}
cdnvm(){ \cd "$@"; nvmuse;}
alias cd='cdnvm'
nvmuse