nvm でバージョンを切り替えるとグローバルインストールした npm パッケージが使えない
nvm はバージョンごとに独立した `lib/node_modules` を持つため、切り替えると前のバージョンのグローバルパッケージは PATH から外れる。
`nvm reinstall-packages` か `--reinstall-packages-from` で移送する。
公開:
要約
nvm use で Node.js を切り替えた途端に tsc: command not found のようになるのは、パッケージが消えたわけではありません。
nvm は バージョンごとに独立したグローバル領域 を持っており、切り替えると前のバージョンの lib/node_modules が PATH から外れるためです。
既にインストール済みのバージョン間で移送するなら、移送先を有効化してから nvm reinstall-packages を実行します。
nvm use 22.11.0
nvm reinstall-packages 20.11.0 # 20.11.0 のグローバルパッケージを 22.11.0 へ複製新しいバージョンをこれから入れるなら、インストールと同時に移送できます。
nvm install --reinstall-packages-from=20 22よくある原因
- グローバル領域がバージョンごとに分かれている: 実体は
~/.nvm/versions/node/<version>/lib/node_modulesです。nvm which currentでどの bin が使われているかを確認できます。 - 移送コマンドを打っていない:
nvm install 22は新しい Node を入れるだけで、旧バージョンのパッケージを引き継ぎません。 ~/.npmrcのprefixが残っている: 過去にグローバルインストール先を手動で変えていると、nvm の想定するパスと食い違います。
公式 README もprefix設定は nvm と非互換だと注意しています。- システム Node と混同している:
/usr/local/lib/node_modulesに入れたパッケージは nvm の管理外です。nvm deactivateで PATH を戻すと切り分けられます。
解決策
1. インストール済みバージョン間で移送する
--reinstall-packages-from は nvm install に紐づいたオプションなので、既に入っているバージョン同士では使えません。
この場合は移送先を有効化してから nvm reinstall-packages を単体で実行します。
nvm ls # 移送元・移送先のバージョンを確認
nvm use 22.11.0 # 移送先を有効化
nvm reinstall-packages 20.11.0なお 公式ドキュメント(新しいタブで開く) にあるとおり、この操作で npm 自体のバージョンは変わりません。
2. インストールと同時に移送する
これから新しいバージョンを入れるなら、1 コマンドで済みます。
nvm install --reinstall-packages-from=20 22
nvm install --reinstall-packages-from=current 'lts/*' # 現在有効なバージョンから最新 LTS へnpm も最新にしたい場合は --latest-npm を併用します。
3. .npmrc の prefix を確認する
npm config get prefix
grep -n 'prefix' ~/.npmrc 2>/dev/nullprefix が ~/.nvm/versions/node/... 以外を指していたら、その行を削除して新しいシェルを開き直します。
4. 何が欠けたのかを比較する
切り替え前後で一覧を取って差分を見ると、移送漏れがすぐ分かります。
npm ls -g --depth=0出力に自分が使っている CLI(typescript、pnpm など)が含まれているかを確認してください。