Node.jsのアップデートをするとnpmのグローバルモジュールが消える

タイトルのことで困っていた。

僕はNode.jsのパッケージマネージャにnodebrewを使っているのだけど、先日使おうと思ったノードモジュールが動かなかったのでNodeのバージョンかもしれないと思ってv8.4.0からv9.5.0に変えた。それでその時に気付いたけどタイトル通りv9.5.0にするとnpmの-gで入れていたモジュールがシェルから使えない、ということに気付いた。nodebrew use v8.4.0してv8.4.0に切り替えるとまた使えるようになる。

そういうものっぽい

github.com

これは世界ではデファクトスタンダードっぽいパッケージマネージャnvmのissueだけど、ここを見ていたらどうやらそういうものらしい。異なるnpmとnodeでは互換性が担保されないので単一のグローバルモジュールを異なるnode間で共有するのはムリが生じるからやりたくないということらしい。

自分はてっきりnpmの-gインストールはnodeと分離されて共通なものなのだという認識でいたからこれを問題だと考えてしまっていただけだった。

移行コマンドがある

github.com

nodebrewの場合は公式リポジトリのdocsのAll commandsのなかに密かに1行だけ書かれていて、上のnmvのissue読まなかったら経緯がわからないのでなんのコマンドなのかさっぱりわからないと思う。

$ nodebrew migrate-package <version>

<version>のとこは移行元のバージョン番号を入れる(v8.4.0 という形式で)

ちなみにnvmにも同様のコマンドは上のissueでもあるように用意されている。

github.com

$ nvm install node --reinstall-packages-from=node

シンボリックリンク??

それで、nodebrewで$ nodebrew migrate-package <version>したところ、なんとv8.4.0のグローバルモジュールにシンボリックリンクを貼っているっぽい。

/Users/username/.nodebrew/node/v8.4.0/lib/node_modules #にあるグローバルモジュールへ
/Users/username/.nodebrew/node/v9.5.0/lib/node_modules #にシンボリックリンク設置している

まあ当たり前に問題なく動いているのだけど、これだと以前のnodeのバージョンを消せないではないか!ということになっていてうーむ、と思っている。無限に増え続けるnode.jsは嫌なので困った。今のところはまあいいのだけど……。

nvmの--reinstall-packagesでどういう処理になるのかはわからない。nvmは使っていないので。