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
ってなってる。
何か忘れてる?それともバグ?