Node.jsのバージョン管理にVoltaとfnmを試してみた

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 ってなってる。

何か忘れてる?それともバグ?

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください