JSのツール管理ライブラリVoltaとは

# Voltaとは
[公式](https://volta.sh/)は手間のかからないJavaScriptのツール管理システムと謳っています(The Hassle-Free JavaScript Tool Manager)。
主なユースケースとしてはNode、npmのバージョン管理です。

Voltaには三つの宣伝文句があります。

⚡高速
あらゆるJSツールを素早くシームレスにインストールし、実行することができます。VoltaはRustでビルドされ、軽快な静的バイナリとして出荷されます。

⚡信頼できる
プロジェクトに参加する全員が同じツールを使えるようにし、ワークフローに支障をきたさないようにします。

⚡ユニバーサル
パッケージマネージャ、Nodeランタイム、OSに関係なく、volta installという1つのコマンドで済みます。

他より早くて、コマンド一つでプロジェクト内で共有できて、OSに依存ないようなツールということです。

# Voltaのセットアップ
Voltaのセットアップは簡単にできます。[Getting Started](https://docs.volta.sh/guide/getting-started)に書かれていることの焼き直しになりますが以下のように構築できます。
## Unix
macosなどのunixシステムでは以下のコマンドで導入できます。
```sh
curl https://get.volta.sh | bash
```
zshを利用の方は
```:~/.zshrc
export VOLTA_HOME="$HOME/.volta"
export PATH="$VOLTA_HOME/bin:$PATH"
```
のように自動で追記されます(bashでは.bashrcなどになります)。
これらの設定を反映させるために`source ~/.zshrc`を行うか、ターミナルを再起動させてください。
```sh
volta --version
```
上記のコマンドでバージョンが表示されることを確認できたら、セットアップ完了です。

## Windows
[Windows インストーラー](https://github.com/volta-cli/volta/releases/download/v1.1.0/volta-1.1.0-windows-x86_64.msi)をダウンロードして進めていくと準備ができるそうです(試せていないです)。

# ツールチェーンの管理
ツールチェーンの管理には主に二つのコマンドを利用します。
install用の`volta install`とuninstall用の`volta uninstall`です。
## install
nodeをinstallするとして説明します。
nodeの14.15.5をinstallしたい場合は以下のようなコマンドを入力します。
```sh
volta install node@14.15.5
```
バージョンがメジャーバージョンでしか定まっていない場合は省略することもできます。
```sh
volta install node@14
```
バージョンを省略した場合はLTSのバージョンでinstallされます。
```sh
volta install node
```
最新のバージョンをinstallすることもできます。
```sh
volta install node@latest
```
nodeで行いましたが、npmやyarnのようなパッケージマネージャーも同様の手段でinstallできます。

## manage
nodeパッケージのバージョンをプロジェクト内で固定することができます。これによってvoltaユーザーがプロジェクトに訪れた時に自動的にバージョンを切り替えてくれます。
nodeのバージョンを固定したいときは以下のように入力します。
```sh
volta pin node
```
このコマンドによってpackage.jsonには以下の記述が追加されます。
```json
"volta": {
  "node": "18.12.0",
}
```
npmなども同様の手段で追加することができます。このように記述されていると、このプロジェクトに訪れたときにvoltaが自動で読み取ってtバージョンを設定してくれます。

### globalにinstallしたパッケージ
例えばtscを使うために`npm install --global typescript`とすることは少なくないと思います。これによってPC全体で使っているtypescriptのバージョンで、あるプロジェクトに対してtscをしてしまうという現象が起きてしまいます。
それを避けるためにglobal installを避けていた人もいらっしゃると思いますが、voltaを使用するとプロジェクトごとに選択されているtypescriptのバージョンに切り替えてくれます。
```shell:例
# globalにtypescript4.9.0をインストールして、3.9.4、4.1.5のディレクトリに移動した時の挙動
tsc --version # 4.9.0
cd /path/to/project-using-typescript-3.9.4
tsc --version # 3.9.4

cd /path/to/project-using-typescript-4.1.5
tsc --version # 4.1.5
```
voltaを使うことで今後はglobalな状態を気にせずにglobal installできますし、それによる不整合が起きる心配がなくなります。

# github actions
github actionsではVoltaが提供している[action](https://github.com/volta-cli/action)を用いることでpackage.jsonを元に環境をセットアップしてくれます。簡単に使えることや、公式が提供しているものですので比較的安全で是非利用したいところです。
```yml:[例]テストを行うactions
steps:
- uses: actions/checkout@v3
- uses: volta-cli/action@v3
- run: npm install
- run: npm test
```

# まとめ
これまでnvm や nodeenv などのツールを使ってきましたが、動作の高速さはもちろん導入の簡単さ、OS依存のなさからvoltaには利点があると考えています。さらにpackage.jsonに記述することによってプロジェクト移動によるバージョンの切り替えは複数のプロジェクトを開発する人にとってはかなりDXが向上するのではないかと思います(nodeenvもnvmもバージョンを切り替える設定は面倒ですが行わせることは可能です。)。追い打ちをかけるようにglobalなパッケージの管理も適切に行なってくれるのでとても採用しがいのあるツールだと思いました。導入するのも止めるのも簡単なので興味あれば是非採用してみてください。

# コマンド
コマンド数が少ないので簡単に紹介します。`volta help`や`volta -h`などでも以下のように十分な説明が出てきます。
```
Volta 1.1.0
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 [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)
```
これを読み取るにコマンドは`volta [FLAG] [SUBCOMMANDS]`のように使えるようです。FLAGは`--verbose`で詳しい結果を出力させ、`--quiet`で結果の出力を最小限に、`-v`または`--version`でバージョンの出力、`-h`または`--help`で上の文章を出してくれます。
## fetch
オフラインで使えるようにツールとバージョンをキャッシュしておいてくれるコマンドです。
```
Fetches a tool to the local machine

USAGE:
    volta fetch [FLAGS] <tool[@version]>...

FLAGS:
        --verbose    Enables verbose diagnostics
        --quiet      Prevents unnecessary output
    -h, --help       Prints help information

ARGS:
    <tool[@version]>...    Tools to fetch, like `node`, `yarn@latest` or `your-package@^14.4.3`.
```
## install
オフラインで使えるようにツールとバージョンをキャッシュしておいてくれるコマンドです。fetchと異なる点は、プロジェクト内でバージョンが定まっていなければデフォルトで利用するように設定してくれる点です。
```
Installs a tool in your toolchain

USAGE:
    volta install [FLAGS] <tool[@version]>...

FLAGS:
        --verbose    Enables verbose diagnostics
        --quiet      Prevents unnecessary output
    -h, --help       Prints help information

ARGS:
    <tool[@version]>...    Tools to install, like `node`, `yarn@latest` or `your-package@^14.4.3`.
```
## uninstall
globalなパッケージを削除するコマンドです。yarnやpnpmなどを削除したりします。
```
Uninstalls a tool from your toolchain

USAGE:
    volta uninstall [FLAGS] <tool>

FLAGS:
        --verbose    Enables verbose diagnostics
        --quiet      Prevents unnecessary output
    -h, --help       Prints help information

ARGS:
    <tool>    The tool to uninstall, e.g. `node`, `npm`, `yarn`, or <package>
```
## pin
プロジェクトのpackage.jsonにツールのバージョンを記載するコマンドです。
```
Pins your project's runtime or package manager

USAGE:
    volta pin [FLAGS] <tool[@version]>...

FLAGS:
        --verbose    Enables verbose diagnostics
        --quiet      Prevents unnecessary output
    -h, --help       Prints help information

ARGS:
    <tool[@version]>...    Tools to pin, like `node@lts` or `yarn@^1.14`.
```
## list
voltaにあるツールを表示してくれます。`volta list node`のように一種類だけの一覧だけでなく、`volta list all`のように全て表示させることもできます。このコマンドのFLAGSには`-c(--current)`や`-d(--default)`なども指定できます。
```
Displays the current toolchain

USAGE:
    volta list [FLAGS] [OPTIONS] [tool]

FLAGS:
    -c, --current    
            Show the currently-active tool(s).
            
            Equivalent to `volta list` when not specifying a specific tool.
    -d, --default    
            Show your default tool(s).

        --verbose    
            Enables verbose diagnostics

        --quiet      
            Prevents unnecessary output

    -h, --help       
            Prints help information


OPTIONS:
        --format <format>    
            Specify the output format.
            
            Defaults to `human` for TTYs, `plain` otherwise. [possible values: human, plain]

ARGS:
    <tool>    
            The tool to lookup: `all`, `node`, `yarn`, or the name of a package or binary.
```
## completions
使っているシェルに対して入力したシェルの補完を生成してくれます。
```
Generates Volta completions

By default, completions will be generated for the value of your current shell,
shell, i.e. the value of `SHELL`. If you set the `<shell>` option, completions
will be generated for that shell instead.

If you specify a directory, the completions will be written to a file there;
otherwise, they will be written to `stdout`.


USAGE:
    volta completions [FLAGS] [OPTIONS] <shell>

FLAGS:
    -f, --force
            Write over an existing file, if any.

        --verbose
            Enables verbose diagnostics

        --quiet
            Prevents unnecessary output

    -h, --help
            Prints help information


OPTIONS:
    -o, --output <out_file>
            File to write generated completions to


ARGS:
    <shell>
            Shell to generate completions for [possible values: zsh, bash, fish, powershell,
            elvish]
```
## which
voltaで起動するツールのバイナリの位置を返します。
```
Locates the actual binary that will be called by Volta

USAGE:
    volta which [FLAGS] <binary>

FLAGS:
        --verbose    Enables verbose diagnostics
        --quiet      Prevents unnecessary output
    -h, --help       Prints help information

ARGS:
    <binary>    The binary to find, e.g. `node` or `npm`
```
## setup
Volta shimディレクトリを含むように現在のユーザーのPATHを変更することにより、Voltaを有効にてくれます。
```
Enables Volta for the current user

USAGE:
    volta setup [FLAGS]

FLAGS:
        --verbose    Enables verbose diagnostics
        --quiet      Prevents unnecessary output
    -h, --help       Prints help information
```
## run
指定したバージョンとツールでコマンドを実行することができます。
```
Run a command with custom Node, npm, and/or Yarn versions

USAGE:
    volta run [FLAGS] [OPTIONS] <command> [--] [args]...

FLAGS:
        --bundled-npm    Forces npm to be the version bundled with Node
        --no-yarn        Disables Yarn
        --verbose        Enables verbose diagnostics
        --quiet          Prevents unnecessary output
    -h, --help           Prints help information

OPTIONS:
        --node <version>         Set the custom Node version
        --npm <version>          Set the custom npm version
        --yarn <version>         Set the custom Yarn version
        --env <NAME=value>...    Set an environment variable (can be used multiple times)

ARGS:
    <command>    The command to run
    <args>...    Arguments to pass to the command
```
## help
helpを出してくれます。出力は最初に紹介した通りです。
```
Prints this message or the help of the given subcommand(s)

USAGE:
    volta help [subcommand]...

ARGS:
    <subcommand>...    The subcommand whose help message to display
```