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だ。ダウンロードしたら普通のアプリ同様にインストールすればいい。
[email protected]: Documents > volta --version
1.0.8
ヘルプを見るとこんな感じ。
[email protected]: 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
。
[email protected]: Documents > volta install [email protected]
success: installed and set [email protected] (with [email protected]) as default
[email protected]
という書き方をしてるのは、Volta が Node.js だけでなく npm や yarn のバージョン管理にも対応してるから。ともかく Node 14 系の最新版がインストールされた。
[email protected]: Documents > node -v
v14.20.0
Node 16 系もインストールしてみる。
[email protected]: Documents > volta install [email protected]
success: installed and set [email protected] (with n[email protected]) as default
[email protected]: Documents > node -v
v16.17.0
volta list all
でインストールされている Node.js のリストが表示される。
[email protected]: Documents > volta list node
⚡️ Node runtimes in your toolchain:
v14.20.0
v16.17.0 (default)
プロジェクトごとにバージョンを分けることもできる。Volta では package.json に利用するバージョンが記載される。サンプルを作って試してみよう。
[email protected]: Documents > cd node-sample
[email protected]: 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
コマンド。
[email protected]: node-sample > volta pin [email protected]
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
で確認。
[email protected]: node-sample > node -v
v14.20.0
プロジェクトのディレクトリを抜けると、デフォルトのバージョンに戻る。
[email protected]: node-sample > cd ..
[email protected]: Documents > node -v
v16.17.0
fnm
fnm は Fast Node Manager の略だそうだ。公式サイトは見当たらないんだけど、GitHub で公開されている。
Windows にインストールするには Chocolatey を使う。PowerShell を「管理者として実行」して、次のコマンドでインストール。
[email protected]: Documents > choco install fnm
PowerShell で使うため、設定ファイルに次の行を書き足す。
fnm env --use-on-cd | Out-String | Invoke-Expression
PowerShell の設定ファイルは $profile と打ち込めばパスを表示してくれる。
[email protected]: 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)
でも、これだけだとまだ使えない。
[email protected]: 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 を起動しなおしたら使えるようになった。
[email protected]: 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 がデフォルトになってる。
[email protected]: Documents > fnm list
* v14.20.0
* v16.17.0 default
* system
[email protected]: Documents > node -v
v16.17.0
切り替えるには fnm use
コマンド。
[email protected]: Documents > fnm use 14
Using Node v14.20.0
[email protected]: Documents > node -v
v14.20.0
ところで system
ってのは何だろう?
[email protected]: Documents > fnm use system
Bypassing fnm: using system node
[email protected]: 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
コマンドでインストール済みのバージョンを指定してやれば直る。
[email protected]: Documents > fnm use 16
Using Node v16.17.0
[email protected]: Documents > node -v
v16.17.0
プロジェクトごとにバージョンを使い分けるには次のようにする。
[email protected]: Documents > mkdir node-sample2
[email protected]: Documents > cd node-sample2
[email protected]: node-sample2 > npm init
[email protected]: node-sample2 > fnm use 14
[email protected]: node-sample2 > node -v > .node-version
fnm では Volta と違って .node-version ファイルに保存される。中身は次のようになってる。
[email protected]: node-sample2 > cat .node-version
v14.20.0
.node-version ファイルがあるディレクトリに移動すると、自動的にバージョンを切り替えてくれる。いったん上のディレクトリに移動し、v16.17.0 に変更した後、もう一度プロジェクトのディレクトリに戻ると、v14.20.0 に切り替わる。
[email protected]: node-sample2 > node -v
v14.20.0
[email protected]: node-sample2 > cd ..
[email protected]: Documents > fnm use 16.17.0
Using Node v16.17.0
[email protected]: Documents > node -v
v16.17.0
[email protected]: Documents > cd node-sample2
Using Node v14.20.0
[email protected]: node-sample2 > node -v
v14.20.0
が、上のディレクトリに戻っても v16.17.0 には切り替わってくれない。どうも .node-version ファイルがないディレクトリに移動したときには切り替えが発生しないみたいだ。どうしようかと思ったら fnm default
コマンドがあった。
[email protected]: Documents > fnm default v16.17.0
[email protected]: Documents > node -v
v14.20.0
[email protected]: Documents > fnm use 16
Using Node v16.17.0
[email protected]: Documents > node -v
v16.17.0
[email protected]: Documents > cd node-sample2
Using Node v14.20.0
[email protected]: node-sample2 > node -v
v14.20.0
[email protected]: node-sample2 > cd ..
[email protected]: Documents > node -v
v14.20.0
なのに期待通り動作しないじゃない。よくよくみると上のほうで fnm list
コマンドを実行したときの出力に v16.17.0 が default
ってなってる。
何か忘れてる?それともバグ?