Node.jsのバージョン管理ツール多すぎ問題
Ruby なら rbenv、Python なら pyenv で決まり、みたいなバージョン管理ツールだけど、Node.js ではやたらと乱立していてどれを使うのがいいのかよくわからない。この問題自体はいろんなところで書かれていて、今回ググった中では↓このページがよくまとまっていた。
このページに挙げられているツールは以下の通り:
- nvm
- n
- volta
- asdf
- nodenv
- fnm
- nvs
- nodebrew
nvm、n、nodenv は前に試したことがある。ほかは聞いたことだけあったり、初めて知ったりだ。
いずれにせよ、JavaScript (Node.js)は Ruby や Python ほど使わないこともあって今までテキトーにしてたんだけど、静的サイトジェネレータの 11ty を試したこと(しかも Windows で)がきっかけで、少しまじめに考えてみようという気になった。なので Linux でも Windows でも使えるのが最低条件だ。
で、どれがいいかというと、上のページでは volta を薦めている。ほかには「Windows なら fnm がいい」というページがいくつか見つかった。そういうわけでこの2つを試してみることにする。どちらも Rust で書かれている。
Volta
公式サイトから Windows 用のインストーラをダウンロードする。
最新バージョンは1.0.8だ。ダウンロードしたら普通のアプリ同様にインストールすればいい。
takatoh@sofa: Documents > volta --version 1.0.8
ヘルプを見るとこんな感じ。
takatoh@sofa: Documents > volta --help Volta 1.0.8 The JavaScript Launcher ⚡ To install a tool in your toolchain, use `volta install`. To pin your project's runtime or package manager, use `volta pin`. USAGE: volta.exe [FLAGS] [SUBCOMMAND] FLAGS: --verbose Enables verbose diagnostics --quiet Prevents unnecessary output -v, --version Prints the current version of Volta -h, --help Prints help information SUBCOMMANDS: fetch Fetches a tool to the local machine install Installs a tool in your toolchain uninstall Uninstalls a tool from your toolchain pin Pins your project's runtime or package manager list Displays the current toolchain completions Generates Volta completions which Locates the actual binary that will be called by Volta setup Enables Volta for the current user / shell run Run a command with custom Node, npm, and/or Yarn versions help Prints this message or the help of the given subcommand(s)
Node.js をインストールするには volta install
。
takatoh@sofa: Documents > volta install node@14 success: installed and set [email protected] (with [email protected]) as default
node@14
という書き方をしてるのは、Volta が Node.js だけでなく npm や yarn のバージョン管理にも対応してるから。ともかく Node 14 系の最新版がインストールされた。
takatoh@sofa: Documents > node -v v14.20.0
Node 16 系もインストールしてみる。
takatoh@sofa: Documents > volta install node@16 success: installed and set [email protected] (with [email protected]) as default takatoh@sofa: Documents > node -v v16.17.0
volta list all
でインストールされている Node.js のリストが表示される。
takatoh@sofa: Documents > volta list node ⚡️ Node runtimes in your toolchain: v14.20.0 v16.17.0 (default)
プロジェクトごとにバージョンを分けることもできる。Volta では package.json に利用するバージョンが記載される。サンプルを作って試してみよう。
takatoh@sofa: Documents > cd node-sample takatoh@sofa: node-sample > npm init
この状態で package.json はこんなふうになっている。
{ "name": "sample", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" }
このプロジェクトに特定の Node.js のバージョンを指定するには volta pin
コマンド。
takatoh@sofa: node-sample > volta pin node@14 success: pinned [email protected] (with [email protected]) in package.json
バージョンの指定は package.json に書き込まれ、次のようになる。
{ "name": "sample", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "volta": { "node": "14.20.0" } }
node -v
で確認。
takatoh@sofa: node-sample > node -v v14.20.0
プロジェクトのディレクトリを抜けると、デフォルトのバージョンに戻る。
takatoh@sofa: node-sample > cd .. takatoh@sofa: Documents > node -v v16.17.0
fnm
fnm は Fast Node Manager の略だそうだ。公式サイトは見当たらないんだけど、GitHub で公開されている。
Windows にインストールするには Chocolatey を使う。PowerShell を「管理者として実行」して、次のコマンドでインストール。
takatoh@sofa: Documents > choco install fnm
PowerShell で使うため、設定ファイルに次の行を書き足す。
fnm env --use-on-cd | Out-String | Invoke-Expression
PowerShell の設定ファイルは $profile と打ち込めばパスを表示してくれる。
takatoh@sofa: Documents > $profile C:\Users\takatoh\Documents\PowerShell\Microsoft.PowerShell_profile.ps1
これで準備は完了。
Node.js をインストールするには fnm install
コマンドを使う。16系をインストールしてみよう。
takatoh@sofa: Documents > fnm install 16 Installing Node v16.17.0 (x64)
でも、これだけだとまだ使えない。
takatoh@sofa: Documents > node -v node: The term 'node' is not recognized as a name of a cmdlet, function, script file, or executable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
PowerShell を起動しなおしたら使えるようになった。
takatoh@sofa: Documents > node -v v16.17.0
14系もインストールしてみよう。
takatoh@sofa: Documents > fnm install 14 Installing Node v14.20.0 (x64)
fnm list
コマンドでインストール済みのバージョンを確認できる。v14.20.0 とv16.17.0 がインストールされてるけど、この時点では v16.17.0 がデフォルトになってる。
takatoh@sofa: Documents > fnm list * v14.20.0 * v16.17.0 default * system takatoh@sofa: Documents > node -v v16.17.0
切り替えるには fnm use
コマンド。
takatoh@sofa: Documents > fnm use 14 Using Node v14.20.0 takatoh@sofa: Documents > node -v v14.20.0
ところで system
ってのは何だろう?
takatoh@sofa: Documents > fnm use system Bypassing fnm: using system node takatoh@sofa: Documents > node -v node: The term 'node' is not recognized as a name of a cmdlet, function, script file, or executable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
たぶん、fnm の管理下にない、もとからインストールされてるバージョンのことだな。今回の場合はそんなものはないのでエラーが出てる、と。fnm use
コマンドでインストール済みのバージョンを指定してやれば直る。
takatoh@sofa: Documents > fnm use 16 Using Node v16.17.0 takatoh@sofa: Documents > node -v v16.17.0
プロジェクトごとにバージョンを使い分けるには次のようにする。
takatoh@sofa: Documents > mkdir node-sample2 takatoh@sofa: Documents > cd node-sample2 takatoh@sofa: node-sample2 > npm init takatoh@sofa: node-sample2 > fnm use 14 takatoh@sofa: node-sample2 > node -v > .node-version
fnm では Volta と違って .node-version ファイルに保存される。中身は次のようになってる。
takatoh@sofa: node-sample2 > cat .node-version v14.20.0
.node-version ファイルがあるディレクトリに移動すると、自動的にバージョンを切り替えてくれる。いったん上のディレクトリに移動し、v16.17.0 に変更した後、もう一度プロジェクトのディレクトリに戻ると、v14.20.0 に切り替わる。
takatoh@sofa: node-sample2 > node -v v14.20.0 takatoh@sofa: node-sample2 > cd .. takatoh@sofa: Documents > fnm use 16.17.0 Using Node v16.17.0 takatoh@sofa: Documents > node -v v16.17.0 takatoh@sofa: Documents > cd node-sample2 Using Node v14.20.0 takatoh@sofa: node-sample2 > node -v v14.20.0
が、上のディレクトリに戻っても v16.17.0 には切り替わってくれない。どうも .node-version ファイルがないディレクトリに移動したときには切り替えが発生しないみたいだ。どうしようかと思ったら fnm default
コマンドがあった。
takatoh@sofa: Documents > fnm default v16.17.0 takatoh@sofa: Documents > node -v v14.20.0 takatoh@sofa: Documents > fnm use 16 Using Node v16.17.0 takatoh@sofa: Documents > node -v v16.17.0 takatoh@sofa: Documents > cd node-sample2 Using Node v14.20.0 takatoh@sofa: node-sample2 > node -v v14.20.0 takatoh@sofa: node-sample2 > cd .. takatoh@sofa: Documents > node -v v14.20.0
なのに期待通り動作しないじゃない。よくよくみると上のほうで fnm list
コマンドを実行したときの出力に v16.17.0 が default
ってなってる。
何か忘れてる?それともバグ?