【Node.js】何回 npm install しても最新のパッケージが入らない原因はコレかも

## 概要
ある条件下で、そうとは気づかずに「`npm install パッケージ名@latest`」と指定しても、version（バージョン）確認コマンドでずっと最新が入らない事件が発生し、「なんでだろうな〜」と色々調査したところ、原因と解決法がわかったので、その内容を記載します。

npm install でパッケージをインストールしようとしても、なぜかバージョン確認してみたら意図したバージョンで入っていないという事象がある場合、パッケージによらず、同様の原因で発生している人が多いのではないかと思ったので、その備忘録です。

### 前提
筆者の使用 PC は Mac です（iMac Pro）。

## 事象（時系列）
上から順に出来事を羅列します。

- Node.js を公式サイトからダウンロードし、手動で入れる
- Angular / Angular CLI を使用した開発をする
  - @angular/cli というパッケージを npm でインストールする
- 手動インストールをやめ、nodenv で管理する運用に変える
  - nodenv は Homebrew でインストールしている
- node 管理ツールを Volta に変更する（Volta 便利です！）
  - Node.js を **v20.x** にバージョンアップする
- Angular の最新バージョンで開発する手順をドキュメントに残そうとする
- Angular CLI のインストール手順を記載中、最新バージョンがどうしてもグローバルに入らないことに気づく
  - `npm install -g @angular/cli` を実行しても、バージョン確認（`ng version`）をするとどうしても古いバージョンが表示される
  - 執筆時点の `@angular/cli` の最新バージョン： **v17.x**
  - インストール後に確認したバージョン： **v11.x**
- どの記事を見ても、「古いパッケージを `npm uninstall` し、最新版を `npm install` しなさい」としか書いておらず、困る。
- どうしたら良いかを原因調査し、無事に解決

### 解決しなかったコマンド
検索すると一番よく出てくる方法である、以下では解決しませんでした。
```bash
# 古いバージョンを一旦アンインストール
$ npm uninstall -g @angular/cli

# npm キャッシュのクリーンアップ
$ npm cache clean --force

# 最新版をインストール
$ npm install -g @angular/cli@latest
```

Angular CLI のバージョン確認

```bash
# バージョン確認コマンド
$ ng version

# 結果 (v11 なので古いまま)
     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI: 11.2.8
Node: 20.10.0
OS: darwin x64

Angular: 
... 
Ivy Workspace: 

Package                      Version
------------------------------------------------------
@angular-devkit/architect    0.1102.8 (cli-only)
@angular-devkit/core         11.2.8 (cli-only)
@angular-devkit/schematics   11.2.8 (cli-only)
@schematics/angular          11.2.8 (cli-only)
@schematics/update           0.1102.8 (cli-only)
```

## 原因
::: note info
**原因**
Volta 導入後に、導入前の 既存の古い node モジュールを削除しなかったから。
:::

※ Volta とは、Rust 製の比較的新しい Node バージョン管理ツールです。nodenv 等よりも、軽くて早くて柔軟で使いやすいので乗り換えました。

#### Volta の管理ディレクトリ
Volta は以下のディレクトリで、対象となるパッケージやライブラリのインストールしたものを管理していました（Mac の場合）。

```bash
# Volta 全体の管理ディレクトリ
/Users/{ユーザ名}/.volta/tools/image/

# Volta の Node.js (v20) の管理ディレクトリ
/Users/{ユーザ名}/.volta/tools/image/node/20.10.0/
```

#### Volta 導入以前の node モジュールの管理ディレクトリ

しかし、通常の node モジュール（npm パッケージ）の管理ディレクトリは以下です（Mac の場合）。
```bash
# 通常の node モジュールの管理ディレクトリ
/usr/local/lib/node_modules
```

#### Volta 導入前後の管理場所の違い
つまり、Volta で　npm install をしても、古い node モジュールに古いもの（今回なら `@angular/cli`）が残っており、こいつが古いままなので、うまく動きませんでした。

```bash
# 古い node モジュールディレクトリ
$ ls /usr/local/lib/node_modules
@angular	@vue		corepack	firebase-tools	npm		yarn

# Volta の node モジュールディレクトリ
$ ls /Users/{ユーザ名}/.volta/tools/image/node/20.10.0/lib/node_modules/
corepack	npm

$ ls /Users/{ユーザ名}/.volta/tools/image/node/20.10.0/lib/node_modules/npm/node_modules
### たくさん出てくるけど、この中に "@angular" はなし
```

今回はたまたま **Volta** で発生した出来事ですが、ピュアな Node.js および npm を運用した方や、他のツールを使用してから他へ乗り換えた場合、管理ディレクトリが異なることで、同様の事象が発生する方がいるかもしれません。

::: note warn
**結論**
Node.js を扱う時は、新しくツールを乗り換える場合、npm パッケージ管理がどこになっているのかを確認するようにしましょう！
:::

## 対応

古い node モジュールを直接手動で削除します
```bash
# 削除コマンド (sudo なのでパスワード聞かれるかも)
sudo rm -rf /usr/local/lib/node_modules/@angular
```

無事に消えたようです。
```bash
# バージョン確認コマンド
$ ng version                                      

# 実行結果
zsh: command not found: ng
```

もう一度インストールします（安定版なので末尾 `@latest` は不要）
```bash
# インストールコマンド
npm install -g @angular/cli
```

意図したバージョンが入っているか確認します。
```bash
# バージョン確認コマンド
$ ng version

# 結果 (v17 になったので OK!)
     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI: 17.0.7
Node: 20.10.0
Package Manager: npm 10.2.3
OS: darwin x64

Angular: 
... 

Package                      Version
------------------------------------------------------
@angular-devkit/architect    0.1700.7 (cli-only)
@angular-devkit/core         17.0.7 (cli-only)
@angular-devkit/schematics   17.0.7 (cli-only)
@schematics/angular          17.0.7 (cli-only)
```

## まとめ
Node.js の管理ツールは色々あるけど、ツールを変える時はファイルの管理方式などに注意しましょう🙌

まずは which コマンドで場所確認するのが良いです。
```bash
# 確認コマンド
$ which ng

# 実行結果 (Volta 管理ディレクトリに入っている場合)
/Users/{ユーザ名}/.volta/bin/ng
```

※ 指摘にもあったので追記。コメントありがとうございます🙌