はじめに
node,npmのパッケージ管理ツールとしてnodenvを使用していましたが、Voltaが良さそうなので試しに導入することにしました。Volta はNode.js環境とそのエコシステム(npm、Yarn、pnpmなど)を効率的に管理するためのツールとして開発されています。
Voltaのインストール方法
実行環境は下記のとおりです。
wsl --version WSL バージョン: 2.2.4.0 カーネル バージョン: 5.15.153.1-2 WSLg バージョン: 1.0.61 MSRDC バージョン: 1.2.5326 Direct3D バージョン: 1.611.1-81528511 DXCore バージョン: 10.0.26091.1-240325-1447.ge-release Windows バージョン: 10.0.22631.4037
また、nodenvはインストール済みでそのまま残します。
後述しますが、環境変数などで注意が必要ですが、基本的には独立し、それぞれ動作に影響は与えない認識なのでそのままにします。
$ nodenv --version nodenv 1.5.0+49.a008938
インストールは公式手順に従いします。
$ curl https://get.volta.sh | bash
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 10460 100 10460 0 0 15761 0 --:--:-- --:--:-- --:--:-- 15753
Installing latest version of Volta (2.0.1)
Checking for existing Volta installation
Fetching archive for Linux, version 2.0.1
######################################################################## 100.0%
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!
シェルを再起動すると以下の環境変数が追加されます。
export VOLTA_HOME="$HOME/.volta" export PATH="$VOLTA_HOME/bin:$PATH"
コマンドも実行できるようになりました。
$ volta --version 2.0.1
$ volta --help
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 [OPTIONS] [COMMAND]
Commands:
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, pnpm, and/or Yarn versions
help Print this message or the help of the given subcommand(s)
Options:
--verbose
Enables verbose diagnostics
--very-verbose
Enables trace-level diagnostics
--quiet
Prevents unnecessary output
-v, --version
Prints the current version of Volta
-h, --help
Print help (see a summary with '-h')
次にバージョンを確認してみます。
コマンドについて
コマンドについてnodenv環境との併用を踏まえた確認をします。
nodenvでインストールしたnodeのバージョン
$ node -v v22.8.0
voltaでインストールした後のnodeのバージョン
$ volta install node success: installed and set node@20.17.0 (with npm@10.8.2) as default # 変更された。 $ node -v v20.17.0
これはnodeおよび、npmのパスがvolta-shimのシンボリックリンクであり、volta-shimバイナリが要求されたコマンドに応じて実行されているためです。
なので、nodenvのパスがvoltaよりも後に追加される場合はコマンドの挙動も変わるため注意が必要という認識です。
一方でnodenvのコマンドはシェルスクリプトで記述されており、依存関係もvoltaとは異なるため競合はしないという理解です。
補足としてnodenvで同様にサポートするnpm,npxについても同様にシェルスクリプトで記述されています。
$ file $HOME/.nodenv/bin/../libexec/nodenv /home/[username]/.nodenv/bin/../libexec/nodenv: Bourne-Again shell script, ASCII text executable
$PATHの確認
$ echo $PATH /home/[username]/.volta/bin:/home/[username]/.local/bin:/home/[username]/.volta/bin:/home/[username]/.cargo/bin:/home/[username]/.nodenv/shims:/home/[username]/.nodenv/bin:
コマンドのフルパス
$ which node /home/[username]/.volta/bin/node $ which npm /home/[username]/.volta/bin/npm
$VOLTA_HOME/binの確認
$ ls -l $VOLTA_HOME/bin node -> /home/[username]/.volta/bin/volta-shim npm -> /home/[username]/.volta/bin/volta-shim npx -> /home/[username]/.volta/bin/volta-shim pnpm -> /home/[username]/.volta/bin/volta-shim volta volta-migrate volta-shim yarn -> /home/[username]/.volta/bin/volta-shim yarnpkg -> /home/[username]/.volta/bin/volta-shim
バイナリ実行ファイルの確認
$ file $VOLTA_HOME/bin/volta /home/[username]/.volta/bin/volta: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=eac7f1dee35e2c47a85ac156c4c767a23c6d6982, with debug_info, not stripped $ file $VOLTA_HOME/bin/volta /home/[username]/.volta/bin/volta: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=eac7f1dee35e2c47a85ac156c4c767a23c6d6982, with debug_info, not stripped $ file $VOLTA_HOME/bin/volta-migrate /home/[username]/.volta/bin/volta-migrate: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=b98371e4a4976765b8be5a6356e1618fc443732b, with debug_info, not stripped
使用例
以下では個人プロジェクトを例にコマンドの使用例を示します。
volta install node@x.x.xでnodeをインストールします。
デフォルトをv22.8.0とします。
$ volta list all
⚡️ User toolchain:
Node runtimes:
v20.16.0
v20.17.0
v22.8.0 (default)
Package managers:
Yarn:
v4.4.1-git.20240825.hash-b2f315f6 (default)
Packages:
次に現在のnodenvの情報を記載します。
# global設定 $ nodenv versions system 22.6.0 * 22.7.0 (set by /home/[username]/dev/twitter-video-dl-node/.node-version) 22.8.0 # local設定 $ nodenv versions system * 22.6.0 (set by /home/[username]/.nodenv/version) 22.7.0 22.8.0
プロジェクト構成を示します。
$ tree -a -L 1 . ├── .git ├── .gitignore ├── .node-version ├── README.md ├── package-lock.json ├── package.json ├── src ├── test └── twitter-video-dl-node.js 3 directories, 6 files
この状態でnpm installを実行すると22.8.0でインストール動作します。
これはvoltaで追加したnodeのdefaultです。
$ npm install --verbose # 省略 Run `npm audit` for details. npm verbose cwd /home/[usertname]/dev/twitter-video-dl-node npm verbose os Linux 5.15.153.1-microsoft-standard-WSL2 npm verbose node v22.8.0 npm verbose npm v10.8.2 npm verbose exit 0 npm info ok
次に実際のプロジェクト以下でバージョンを指定します。
するとpackage.jsonにvoltaセクションが追加されます。
$ volta pin node@20.16.0 success: pinned node@20.16.0 (with npm@10.8.1) in package.json
"volta": { "node": "20.16.0" }
$ volta list all
⚡️ User toolchain:
Node runtimes:
v20.16.0 (current @ /home/[username]/dev/twitter-video-dl-node/package.json)
v20.17.0
v22.8.0 (default)
Package managers:
Yarn:
v4.4.1-git.20240825.hash-b2f315f6 (default)
Packages:
npm installを実行します。
すると、voltaでlocal指定(pin)した20.16.0が追加されました。
$ npm install --verbose # 省略 Run `npm audit` for details. npm verbose cwd /home/[usertname]/dev/twitter-video-dl-node npm verbose os Linux 5.15.153.1-microsoft-standard-WSL2 npm verbose node v20.16.0 npm verbose npm v10.8.1 npm verbose exit 0
次にvoltaで追加したnodeを削除した場合を確認します。
$ rm -rf ~/.volta/tools/image/node/*
$ volta list all
⚡️ No Node runtimes installed!
You can install a runtime by running `volta install node`. See `volta help install` for
details and more options.
package.json にvoltaセクションが記載されている場合はnodeを追加してインストール処理を実行されました。
$ rm -rf node_modules
$ npm install --verbose
npm verbose cli /home/[usertname]/.volta/tools/image/node/20.16.0/bin/node /home/[usertname]/.volta/tools/image/node/20.16.0/bin/npm
npm info using npm@10.8.1
npm info using node@v20.16.0
npm verbose title npm install
npm verbose argv "install" "--loglevel" "verbose"
# 省略
npm verbose cwd /home/[usertname]/dev/twitter-video-dl-node
npm verbose os Linux 5.15.153.1-microsoft-standard-WSL2
npm verbose node v20.16.0
npm verbose npm v10.8.1
npm verbose exit 0
npm info ok
$ volta list all
⚡️ User toolchain:
Node runtimes:
v20.16.0 (current @ /home/[usertname]/dev/twitter-video-dl-node/package.json)
Package managers:
Yarn:
v4.4.1-git.20240825.hash-b2f315f6 (default)
Packages:
一方でpackage.json にvoltaセクションが記載を削除してもdefaultのバージョンを追加してインストール動作しました。
これはデフォルトの情報をplatform.jsonで管理しているためです。
$ cat ~/.volta/tools/user/platform.json
{
"node": {
"runtime": "22.8.0",
"npm": null
},
"pnpm": null,
"yarn": "4.4.1-git.20240825.hash-b2f315f6"
}
platform.jsonを削除した場合は、nodenvのバージョン(下記ではshimによるカレントディレクトリのバージョン)で追加されました。
$ npm install --verbose npm verbose cli /home/[usertname]/.nodenv/versions/22.7.0/bin/node /home/[usertname]/.nodenv/versions/22.7.0/bin/npm npm info using npm@10.8.2 npm info using node@v22.7.0 npm verbose title npm install npm verbose argv "install" "--loglevel" "verbose" # 省略 Run `npm audit` for details. npm verbose cwd /home/[usertname]/dev/twitter-video-dl-node npm verbose os Linux 5.15.153.1-microsoft-standard-WSL2 npm verbose node v22.7.0 npm verbose npm v10.8.2 npm verbose exit 0 npm info ok
これらの仕様はmain/crates/volta-core/src/run/mod.rsから確認することができます。
以上の確認から、nodenvの場合はnodenv local x.x.xで.node-versionで追加されますが、両方存在していてもパスの指定により競合することはないことがわかりました。
補足:VoltaのNode runtime(default)を変更する方法
voltaにはnodenvにおけるnodenv global <version>のようなコマンドはありません。
Voltaではvolta install node@<version>のように実行すれば設定されます。
<変更前>VoltaのNode runtime(default)
$ volta list all
⚡️ User toolchain:
Node runtimes:
v20.17.0
v22.7.0 (default)
v22.8.0
Package managers:
Yarn:
v4.4.1-git.20240825.hash-b2f315f6 (default)
Packages:
volta install node@<version>を実行する
$ volta install node@22.8.0 success: installed and set node@22.8.0 (with npm@10.8.2) as default
<変更後>VoltaのNode runtime(default)
$ cat ~/.volta/tools/user/platform.json
{
"node": {
"runtime": "22.7.0",
"npm": null
},
"pnpm": null,
"yarn": "4.4.1-git.20240825.hash-b2f315f6"
$ cat ~/.volta/tools/user/platform.json
{
"node": {
"runtime": "22.8.0",
"npm": null
},
"pnpm": null,
"yarn": "4.4.1-git.20240825.hash-b2f315f6"
まとめ
Node.js向けのパッケージツールであるVoltaのインストール方法について紹介しました。
また、実際のプロジェクトとnodenvを用いた使用例の確認から以下の点がわかりました。
nodenvとvoltaはパスやデフォルトのバージョン情報を削除しなければ競合しないvoltaでは、プロジェクトに対してローカル指定する場合はpackage.jsonにvoltaフィールドを追加する(pinコマンドを実行する)。voltaでは、nodenvのように.node-version管理ではなく、package.json、platform.jsonで管理され、nodeやnpm等は、シェルスクリプト形式ではなく、実行バイナリファイル形式で要求されたコマンドに応じて実行される。
最後に、ここ数年でRust製のプロジェクトは増えており、Pythonなど他の言語でもツールとして公開されることが増えてきました。利用しやすい(特に速度面)反面、環境依存など考慮すべき点など注意が必要ですが、使いやすさがあり、速くてバグが少ないのであれば利用したいという思いです。その点、Voltaは移行も使い勝手も問題ない印象のため、今後利用していきたいと感じました。また、気になる点があれば追記をしたいと思います。
以上です。