Nodeのバージョン管理はVoltaがいいかもしれない

Nodeのバージョン切り替えツールは nodenv を使用してますが、もっと便利なものがないか探したところ Volta というものを見つけたので試してみました。

環境
Volta 1.0.6
WSL2 Ubuntu-20.04

目次

Voltaとは

Voltaを簡単に説明すると、Node、パッケージマネージャー(npm, yarn)、グローバルパッケージを管理できるツールマネージャーです。
Nodeに加え、パッケージマネージャーとグローバルパッケージも管理できる優れものです。

このツールの特徴は3つで、速い信頼できるユニバーサルとなっています。以下は公式の自動翻訳です。

速い

JSツールをすばやくシームレスにインストールして実行します。VoltaはRustに組み込まれており、きびきびとした静的バイナリとして出荷されます。

Install and run any JS tool quickly and seamlessly! Volta is built in Rust and ships as a snappy static binary.

信頼できる

プロジェクトの全員が、ワークフローに干渉することなく、同じツールを使用できるようにします。

Ensure everyone in your project has the same tools—without interfering with their workflow.

ユニバーサル

パッケージマネージャー、ノードランタイム、またはOSに関係なく、必要なコマンドは1つだけですvolta install

No matter the package manager, Node runtime, or OS, one command is all you need: volta install.

特徴はこんな感じです。

先に結論

nodenvからVoltaに変更したほうがメリットが多いと感じました。

まずVoltaのインストールが curl https://get.volta.sh | bash だけなので簡単です。

次に、後述で同じ内容を書いていますが、Nodeやパッケージマネージャーのバージョン情報はpackage.jsonに記述されます。

package.jsonに記述されたバージョンがインストールされていない場合は、パッケージインストール時に自動でNodeやパッケージマネージャーもインストールされます。

この機能があるので、チームでVoltaを採用しても何も心配しなくて済みそうです。
ただ、Volta自体のバージョンは揃える必要があると思います。

nodenvにも自動でNodeをダウンロードできるプラグインがありますが、Voltaの場合は最初から組み込まれているのが良いところです。

そして対応OSがUnix系とWindowsなので殆どの環境で動かせるのが嬉しいところです。
今回Windowsは試していませんが、開発者モードに切り替える必要があるようです。

個人でもチームでもメリットが多いと感じたので、気になる方は以下にインストールや使い方をざっくり書いているので、よければ読んでみてください。

Voltaのインストール

インストールは非常に簡単で curl https://get.volta.sh | bash を実行するだけです。

curl https://get.volta.sh | bash

# log ---
Installing latest version of Volta (1.0.6)
  Checking for existing Volta installation
  Fetching archive for Linux, version 1.0.6
  Creating directory layout
Extracting Volta binaries and launchers
  Finished installation. Updating user profile settings.
Updating your Volta directory. This may take a few moments...
success: Setup complete. Open a new terminal to start using Volta!

successが表示されたらインストールは完了です。

bash、zsh、およびfishシェルを使用している場合は、インストーラーが自動的に起動スクリプトを設定するとのことで、~/.bashrc (/home/{username}/.bashrc) を確認したところPATHの設定が追記されていました。

export VOLTA_HOME="$HOME/.volta"
export PATH="$VOLTA_HOME/bin:$PATH"

Voltaコマンドを使えるようにするため、ターミナルを再起動するか以下のコマンドでシェルを再起動します。

exec $SHELL -l

再起動したら以下のコマンドを実行してVoltaが使えるか確認します。

volta

# log ---
Volta 1.0.6
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`.
...

上記のような表示がされれば成功です。

次は各ツールのインストールです。

ツールのインストール

Node、パッケージマネージャー、グローバルパッケージ、それぞれインストールを行っていきます。

Nodeのインストール

Nodeのインストールは volta install node と入力するだけです。

volta install node
# success: installed and set node@16.14.2 (with npm@8.5.0) as default

安定版の16.14.2がインストールされました。

バージョンを指定する場合はnode@バージョンでインストールできます。

volta install node@12.22.9

インストール状況の確認

インストールしたバージョンを確認する場合はvolta listコマンドを使用します。

volta list all

# log ---
⚡️ User toolchain:

    Node runtimes:
        v12.22.9 (default)
        v16.14.2

    Package managers:
    Packages:

# volta list = アクティブなツール状態
# volta list all = 全てのツール状態
# volta list node = nodeの状態
# 詳しくは volta list --help

6-8行目のNode runtimes:でインストールしたバージョンが確認できます。

volta listコマンドにはいくつかありますが、volta list all が全ての状態を確認できるので便利です。

Nodeのバージョンが12.22.9(default)となっているので次はバージョンを切り替えてみます。

バージョンの切り替え

Voltaはvolta install最後にインストールしたバージョンがデフォルトになるようです。

インストールだけを行うコマンドではないので勘違いしそうですが、
Voltaの特徴に「必要なコマンドはvolta installだけ」と書かれていたので、シンプルを求めた結果なのだろうと素直に受け止めます。

バージョン切り替えを行ってみます。

node -v
# v12.22.9

volta install node@16.14.2 # バージョン切り替え
# success: installed and set node@16.14.2 (with npm@8.5.0) as default

node -v
# v16.14.2

node 16.14.2はダウンロード済みなので一瞬で切り替わりました。

volta list allを実行すると以下のように 16.14.2 がデフォルトになりました。

volta list all

# log ---
⚡️ User toolchain:

    Node runtimes:
        v12.22.9
        v16.14.2 (default)

デフォルトの切り替え方は分かったので、次はパッケージマネージャーのインストールです。

パッケージマネージャーのインストール

パッケージマネージャーは、npmyarnがインストールできるようなので、試しにyarnをインストールします。

volta install yarn
# success: installed and set yarn@1.22.18 as default

こちらもバージョン指定するときは、volta install yarn@1.10.1 のようにします。

複数バージョンをインストールした後にvolta list allを実行すると以下のようになりました。

volta list all

# log ---
⚡️ User toolchain:

    Node runtimes:
        v12.22.9
        v16.14.2 (default)

    Package managers:
        Yarn:
            v1.10.1 (default)
            v1.22.18

    Packages:

パッケージマネージャーのデフォルトを変更する場合も volta install yarn@1.22.18 のようにします。

次はグローバルパッケージのインストールです。

グローバルパッケージのインストール

グローバルパッケージをインストールする場合はvolta intallコマンド、もしくはパッケージマネージャーのグローバルコマンドでインストールできます。

試しにuuidをインストールしてみます。

volta install uuid
# success: installed uuid@8.3.2 with executables: uuid

volta list allを実行すると以下のようになりました。

volta list all

# log ---
⚡️ User toolchain:

    Node runtimes:
        v12.22.9
        v16.14.2 (default)

    Package managers:
        Yarn:
            v1.10.1
            v1.22.18 (default)

    Packages:
        uuid@8.3.2 (default)
            binary tools: uuid
            platform:
                runtime: node@16.14.2
                package manager: npm@built-in

8, 19行目を見ると、グローバルパッケージはインストールを行った時のNodeバージョンで紐付けられるようです。

公式サイトにもそのような事が書かれていました。

ツールチェーンにパッケージをインストールすると、Voltaは現在のデフォルトのノードバージョンを取得し、ツールをそのエンジンに固定します(詳細については、パッケージバイナリを参照してください)。Voltaは、ツールを更新しない限り、ツールの固定エンジンを変更しません。このようにして、インストールしたツールが背後で変更されないことを確信できます。

When you install a package to your toolchain, Volta takes your current default Node version and pins the tool to that engine (see Package Binaries for more information). Volta won’t change the tool’s pinned engine unless you update the tool, no matter what. This way, you can be confident that your installed tools don’t change behind your back.

試しにNodeのバージョンを12.22.9に切り替えて、gulpをインストールすると以下のようになりました。

volta install node@12.22.9
volta install gulp
volta list all

# log ---
...
    Packages:
        gulp@4.0.2 (default)
            binary tools: gulp
            platform:
                runtime: node@12.22.9
                package manager: npm@built-in
        uuid@8.3.2 (default)
            binary tools: uuid
            platform:
                runtime: node@16.14.2
                package manager: npm@built-in

8-11行目を見ると、切り替えたNodeのバージョン12.22.9でgulpが実行されるように書かれています。
バージョンが固定化されればエラーの心配をしなくていいので良い機能だと思いました。

次にgulpの別バージョンgulp@3を入れてみます。

volta install gulp@3
volta list all

# log ---
⚡️ User toolchain:

    Node runtimes:
        v12.22.9 (default)
        v16.14.2
   ...
    Packages:
        gulp@3.9.1 (default)
            binary tools: gulp
            platform:
                runtime: node@12.22.9
                package manager: npm@built-in
        uuid@8.3.2 (default)
            binary tools: uuid
            platform:
                runtime: node@16.14.2
                package manager: npm@built-in

12行目の部分が変更点で、gulp@4.0.2gulp@3.9.1になってしまいました。

どうやらグローバルパッケージはバージョン管理されないようです。
詳しいことは分かりませんが、現バージョンのVoltaでは複数バージョンの管理はできなさそうです。

これでツールのインストール説明は終わりにして、次はプロジェクトでツールを固定化させる話に進みます。

プロジェクトでツールを固定化する

プロジェクトでツールを固定化させるにはvolta pinコマンドを使用します。

volta pin node
# success: pinned node@16.14.2 (with npm@8.5.0) in package.json

成功するとpackage.jsonにVoltaの設定が追加されます。
nodenvの場合は別ファイルになっていたので、package.jsonで管理されるのは良いところだと思います。

"volta": {
  "node": "16.14.2"
}

バージョンを指定する場合は volta pin node@12.22.9 のようにします。

パッケージマネージャーも設定する場合は同様に volta pin yarn を実行します。
package.jsonは以下のようになりました。

"volta": {
  "node": "16.14.2",
  "yarn": "1.22.18"
}

これだけで設定は完了です。

今後このプロジェクトディレクトリにアクセスすると、各ツールが自動的に指定されたバージョンに切り替わるようになります。

volta list all を実行すると詳しく分かります。

volta list all

# log ---
⚡️ User toolchain:

    Node runtimes:
        v12.22.9
        v16.14.2 (current @ /volta-test/package.json)

    Package managers:
        Yarn:
            v1.10.1
            v1.22.18 (current @ /volta-test/package.json)

    Packages:
        gulp (current @ /volta-test/package.json)
            binary tools: gulp
        uuid@8.3.2 (default)
            binary tools: uuid
            platform:
                runtime: node@16.14.2
                package manager: npm@built-in

current が付いて分かりやすいです。

次はプロジェクトディレクトリで、ツールがインストールされていない状態だとどうなるか試します。

ツールがインストールされていない場合の動作について

試す内容はシンプルにpackage.json のVolta設定を適当なバージョンに変更してパッケージのインストールをします。

"volta": {
  "node": "17.8.0",
  "yarn": "1.19.2"
}

パッケージマネージャーはyarnなのでyarnを実行します。

yarn

# log ---
Fetching node@17.8.0  [==>                                     ]   7%
Fetching yarn@1.19.2  [==>                                     ]   7%
[1/4] Resolving packages...
[2/4] Fetching packages...

自動的に指定バージョンのnodeとyarnがインストールされて、パッケージのインストールが始まりました。

どうやらパッケージをインストールしようとするだけで足りない事を全部やってくれるようです。

これならチームでも安心して使えそうだと思いましたが、実験でパッケージマネージャーの指定はyarnで、わざとnpm iを実行してみました。
そうするとnpm でパッケージがインストールされてしまいました。(package-lock.jsonが作られる)

yarnで自動実行されると予想していましたが、そこまでの機能はないので少し注意が必要です。

アンインストール

各種アンインストール方法です。

Voltaのアンインストール

~/.volta ディレクトリを削除して、~/.bashrcに書き込まれた以下2行を削除して完了です。

export VOLTA_HOME="$HOME/.volta"
export PATH="$VOLTA_HOME/bin:$PATH"

Nodeとパッケージマネージャーのアンインストール

公式サイトを見ると volta uninstall nodevolta uninstall yarn で削除できそうですが、現在は全く動作しないため手動で削除するしかないようです。

Nodeの削除は以下ディレクトリで管理されています。

  • ~/.volta/tools/image/node/{バージョン}
  • ~/.volta/tools/inventory/node/{バージョン}

パッケージマネージャも同様の仕組みになっています。

  • ~/.volta/tools/image/npm/{バージョン}
  • ~/.volta/tools/inventory/npm/{バージョン}
  • ~/.volta/tools/image/yarn/{バージョン}
  • ~/.volta/tools/inventory/yarn/{バージョン}

imageが本体で、inventoryがキャッシュになっています。

グローバルパッケージのアンインストール

volta uninstall パッケージ名、もしくはパッケージマネージャーのアンインストールコマンドで削除できます。

volta uninstall gulp
# Removed executable 'gulp' installed by 'gulp'

補完機能を使う

volta completionsコマンドで補完情報を出力できます。情報を出力するだけなので、ファイルを作って読み込むようにします。

シェルがbashの場合は以下のようにします。

volta completions bash > ~/.volta-completion.bash
echo -e "if [ -f ~/.volta-completion.bash ]; then\n  . ~/.volta-completion.bash\nfi\n" >> ~/.bashrc
exec $SHELL -l

1行目は補完情報を~/.volta-completion.bashに出力。
2行目で~/.bashrc~/.volta-completion.bashを読み込むように設定。
3行目でシェルの再起動。

以下に volta install までタイプして補完情報を表示させてみました。
たぶん各ツールのインストール可能バージョンを表示する機能はないです。

volta install
-h  --help  --quiet  <tool[@version]>...  -V  --verbose  --version

使うコマンドは少ないので補完機能は必要ないかなと思いました。

  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次