voltaの導入と感想

やることが減って新しいことができるようになった。
できるようになったが選べるわけではない。
ずっと避けていたがNodejsをしっかり見て使わざるを得なくなった。
volta
を導入した。
> volta -v
2.0.2
> 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.exe [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)
Nodeはプロジェクトごとにスイッチして切り替えるものと覚えていたがスイッチらしいものが見当たらない。
「volta node 切り替え」――Webで検索。
どうもpackage.json
のvolta
の部分を参照して勝手に切り替えるらしい。
どういうびっくり技術なのか調べる。

調査するポイント
- voltaはランチャー
- 起動する(管理する)配信元
- node
- yarn
- パッケージ
- voltaはランチャーなのか?yarnはパッケージマネージャーなのか?
- そもそもvoltaやyarnが取得するパッケージは検証されているのか

voltaはランチャー 1/?
実行ファイルの確認方法
> where.exe node
C:\Program Files\Volta\node.exe
> where.exe yarn
C:\Program Files\Volta\yarn.cmd
C:\Program Files\Volta\yarn.exe
> Get-Content 'C:\Program Files\Volta\yarn.cmd'
@echo off
"%~dpn0.exe" %*
> comp.exe 'C:\Program Files\Volta\node.exe' 'C:\Program Files\Volta\volta-shim.exe' /M
C:\Program Files\Volta\node.exe と C:\Program Files\Volta\volta-shim.exe を比較しています...
ファイルに違いはありません
> comp.exe 'C:\Program Files\Volta\node.exe' 'C:\Program Files\Volta\yarn.exe' /M
C:\Program Files\Volta\node.exe と C:\Program Files\Volta\yarn.exe を比較しています...
ファイルに違いはありません
volta-shimがどうも本体らしい
ソースコードからビルドして確認
> git checkout v2.0.2
> cargo b -r
> cd .\target\release\
> cp .\volta-shim.exe node.exe
ここでできあがったvolta-shimをnodeとして起動してあげるとインストールされたもの同じ動作をすると思ったがうまく動かない

配置先だけの問題だったようだ。ビルドしてできたvolta-shimをすでに存在するC:\Program Files\Volta\node.exe
と置き換えて使用するとうまく動いた。

voltaはランチャー(2/?)
voltaのソースコードを読む (1/?)
要約
プロジェクトのフォルダ構造は「アプリ本体(exe)」と「同名のライブラリ」でソースコードが分離されていて、これはCLIやGUIを持つOSSのライブラリではffmpeg.exe/ffplay.exe対libffmpeg, obs.exe対libobsなどでもみられる形体である。
先に調べた通りvoltaインストール環境下ではnode.exe
やyarn.exe
はvolta-shim.exe
である。
ソースコードを読むとffmpegやobsの例にならって、volta.exe/volta-shim.exe対volta-coreといった風な構造が見えた。調べた結果、トップレベル(CLI)で見える機能とコア機能の対応関係は下表の通り。
トップレベル機能 | コアロジック | コメント | ソースコードへのリンク |
---|---|---|---|
volta-shim | get_executor | ../run/mod.rs#L75 | |
volta run | get_executor | 呼び出し方がshimと異なるので若干補助機能に差分がある | ../run/mod.rs#L75 |
volta install | ensure_fetch | (ステータス:要確認) | |
volta pin | ensure_fetch | (ステータス:要確認) |

voltaはランチャー(3/3)
voltaのソースコードを読む (2/?)
volta run
ヘルプを確認するとこのような説明が出てくる。
> volta run --help
Run a command with custom Node, npm, pnpm, and/or Yarn versions
Usage: volta.exe run [OPTIONS] <COMMAND>...
Arguments:
<COMMAND>... The command to run, along with any arguments
Options:
--node <version> Set the custom Node version
--npm <version> Set the custom npm version
説明にはないがソースコード[1]を読むとRustの標準ライブラリを通じて環境変数を指定している。
use std::process::{Command, ExitStatus};
:
pub struct ToolCommand {
command: Command,
platform: Option<Platform>,
kind: ToolKind,
}
:
impl ToolCommand {
:
pub fn env<K, V>(&mut self, key: K, value: V)
where
K: AsRef<OsStr>,
V: AsRef<OsStr>,
{
self.command.env(key, value);
}
:
pub fn execute(mut self, session: &mut Session) -> Fallible<ExitStatus> {
:
self.command.env("PATH", path);
:
そのためコマンドvolta run --node v14.16.0 powershell -Command "node -v; pause"
を試しに実行してみると
v14.16.0
続行するには、Enter キーを押してください...:
と返ってきた。うーん変態だ!(ほめてる。)

起動する(管理する)配信元(1/?)
要約
nodeの場合、配信元 https://nodejs.org/dist から取得する。
yarnの場合、配信元 https://registry.npmjs.org/ から取得する。
パッケージの場合は子プロセスとしてyarnが間接的に起動する。このパッケージはVoltaの管理外になる。例外としてグローバルにパッケージをインストールする場合があって、その場合、パッケージはVoltaの管理下に入る。
グローバルにパッケージをインストールする際はVoltaによって環境変数npm_config_prefix
が上書きされるためマシンの設定は無視される。これは環境変数PAHTいわゆる「コマンドサーチパス」という仕組みを利用するOSの都合、同じマシン内でVoltaが他のnodeバージョン管理ソフトと共存できない原因になりうる。
voltaの管理下にあるnodeの確認方法
nodeのプロジェクトフォルダ以外の場所でvolta list
とvolta which
を使う。
> volta list --help
Displays the current toolchain
Usage: volta.exe list [OPTIONS] [tool]
:
> volta which --help
Locates the actual binary that will be called by Volta
Usage: volta.exe which [OPTIONS] <BINARY>
Arguments:
<BINARY> The binary to find, e.g. `node` or `npm`
:
> Test-Path package.json
False
> volta list
⚡️ Currently active tools:
Node: v20.3.0 (default)
Yarn: v1.22.19 (default)
Tool binaries available:
vue (default)
See options for more detailed reports by running `volta list --help`.
> volta which node
C:\Users\:USERNAME\AppData\Local\Volta\tools\image\node\20.3.0\node.exe
> volta which yarn
C:\Users\:USERNAME\AppData\Local\Volta\tools\image\yarn\1.22.19\bin\yarn.cmd
volta pinされたnodeのプロジェクト配下ではwhichの結果が変わる(listの結果も変わるが省略)。
> Test-Path package.json
True
> volta which node
C:\Users\:USERNAME\AppData\Local\Volta\tools\image\node\14.16.0\node.exe
なお、volta listで有効になっていなくてもwhichで見つけることができる。
> volta which npm
C:\Users\:USERNAME\AppData\Local\Volta\tools\image\node\20.3.0\npm.cmd
> volta which pnpm
C:\Program Files\Volta\pnpm.exe

voltaはランチャーなのか?yarnはパッケージマネージャーなのか?(感想)
要旨
voltaはnodeバージョン管理ウェアであって、パッケージマネージャーマネージャーだ。ビルドツールのランチャーであって、ビルドした後のアーティファクトにvoltaが直接かかわることはない……と思う。voltaの全部のソースを読んだわけでない為。
スクラップの書き始めにはyarnとクロスする部分があるのではないかと疑っていたが、少なくとも私がvoltaを使う分にはクロスする部分は全くなさそう。
「そもそもvoltaやyarnが取得するパッケージは検証されているのか」についてはvoltaが仮に直接的にパッケージ管理をしているとしたらといったところがモチベーションだった。
それがなくなってしまったのでまた別のモチベーションがでてきたら調べるものとする。