nodebrewからnodenv（on anyenv）に切り替える（2020年1月版）+ありがちなトラブル

## 動機
`nodebrew` にて手動でプロジェクト毎にnodeのバージョンを切り替えるのが面倒になったので、`.node-version` ファイルで自動切り替えできる`nodenv`で管理しようと思いました。
ひと悶着あり、同じことが起こってる人の役にたつかもしれないので、全体の流れも記録しておくことにしました。その都度、遭遇するかもしれないトラブルシューティングも下のほうに記載しておきましたので、躓いたら見てみてください。

## 最初の状態

### 環境
- Mac
- ターミナル
- zsh

### nodeのバージョンなど

10系と12系のプロジェクトがあるので、都度切り替えている感じです。

```
$ node -v

v10.16.3
```

```
$ which node

/usr/local/bin/nodebrew
```

その他にインストールされていたnodeのバージョン

```
$ nodebrew ls  

v9.11.2
v10.16.3
v12.10.0
v12.12.0
```

npmのバージョンなど

```
$ npm -v

6.13.0
```

```
$ which npm

/Users/user-name/.nodebrew/current/bin/npm
```


## nodebrewを消す
nodebrewがインストールされている状態だとバッティングの可能性があるようなので、思い切って削除します。
`-rf` つけてる `rm` は慎重に。

```
$ rm -rf ~/.nodebrew
```

ばっさり

`.bash_profile` で通しているパスを削除しておく必要があるらしい。

```
$ vi ~/.bash_profile
```

↓のようなのを消しておきましょう

```
export PATH=/Users/user-name/.nodebrew/current/bin:$PATH
```

確認する。これでエラーが返ってきたらばっちりのはず…

```
$ node -v

/usr/local/bin/node
```

おっと…？

## とりあえずanyenv -> nodenvをインストールしてみる

Homebrewで可能でした

```
$ brew install anyenv
```

からの。
初期化？

```
$ anyenv init

# Load anyenv automatically by adding
# the following to ~/.zshrc:

eval "$(anyenv init -)"
```

`.zshrc` ファイルに記述が必要らしいので。

```
$ vi ~/.zshrc
```

まだファイルがなかった場合は下記の１行だけを置いておく形に。

```
eval "$(anyenv init -)"
```

viじゃなくても大丈夫だし、環境によっては `.bashrc` とかに記述の必要があるかも。

どこかに書かれていたけど、以下も必要なのかな？

```
$ anyenv install --init
```

とりあえず都度シェルをきれいに。

```
$ exec $SHELL -l 
```

本題の `nodenv` のインストール。 `anyenv` 経由でできるらしい。

```
$ anyenv install nodenv

（前略）
Install nodenv succeeded!
Please reload your profile (exec $SHELL -l) or open a new session.
```

おけ。指示通りターミナルを初期化して、今の状態を確認してみる。

```
$ exec $SHELL -l
$ nodenv versions

* system => v12.12.0 (set by /Users/user-name/.anyenv/envs/nodenv/version)
```

おぉ？まだ `nodenv` でnodeをインストールしてないけど…まぁええんか？

以前の状態に合わせるために古いnodeもインストール

```
$ nodenv install 10.16.3

nodenv versions        
* system => v12.12.0 (set by /Users/user-name/.anyenv/envs/nodenv/version)
  10.16.3
```

ちゃんと入ったっぽい。

## マシンを３年も使っていると色々と溜め込んだものがありまして

手動で切り替えてみよう

```
$ nodenv global 10.16.3
 
（略）

$ node -v     
         
v12.12.0
```

あかん。なんでや？

どこのnodeを使っているか場所を確認。

```
$ which node

/Users/user-name/.nodebrew/current/bin/node
```

ゾンビnode発見。
もういないはずの、 `nodebrew` の文字が…

確認。

```
$ nodebrew

zsh: command not found: nodebrew
```

やはりゾンビ。
さよならだ。（正直謎…）

```
$ rm -rf /Users/user-name/.nodebrew
```

気を取り直して

```
$ node -v

v13.2.0
```
HAHAHA、冗談はやめてくれYO

```
$ which node

/usr/local/bin/node
```

地縛霊発見。

```
sudo rm -rf /usr/local/bin/node
```

お祓い完了。

```
node -v

zsh: command not found: node
```

ほぅ…

（少しやけくそ目に）

```
$ anyenv install nodenv

$ nodenv versions

* 10.16.3 (set by /Users/user-name/.anyenv/envs/nodenv/version)

$ node -v

zsh: command not found: node
```

おこ。

…
…
…
あ。もしや。

```
$ exec $SHELL -l
$ node -v

v10.16.3
```

いえーす。


## いつから（ry

```
$ npm -v

6.13.1

$ which npm

/usr/local/bin/npm
```

お前もか

```
$ brew uninstall --ignore-dependencies npm

Uninstalling /usr/local/Cellar/node/13.2.0... (4,654 files, 58.8MB)
node 12.12.0 is still installed.
Run `brew uninstall --force node` to remove all versions.

$ node -v
v12.12.0

$ npm -v
6.13.1

$ which npm
/usr/local/bin/npm
```

お祓いがきかないぃ（まぁアンインストールされるバージョンも変なの出てるんですけどね…）
おこ。そろそろ慣れてきたけど。

```
$ which npm

/usr/local/bin/npm

$ rm -rf /usr/local/bin/npm
$ npm -v                   
6.11.3

$ which npm

/Users/user-name/.anyenv/envs/nodenv/shims/npm
```

（ファンファーレが頭の中で鳴り響く）

特定のバージョンのnpmが欲しかったので。

```
$ npm install -g npm@6.13.0
```

こうしておいて、手動でのnodeバージョンを切り替えてnpmもついてくるかテスト

```
$ nodenv global 12.12.0
$ node -v
v12.12.0

$ npm -v
6.13.0

$ nodenv global 10.16.3
$ node -v
v10.16.3

$ npm -v
6.9.0
```

できた

## やっと本題の、 `.node-version`でのローカルの管理

npmにしろnodeを用いる際にnode自体のバージョンによってエラーなどの原因になることがしばしばあります。nodebrewでの管理でプロジェクトごとにこの辺りの事情が異なる場合、プロジェクトをはしごする際に手動でのnodeの切り替えが必要になったりします。
nodenvはコマンドを実行するディレクトリに `.node-version` ファイルがあるとそのファイル内で指定されているバージョンのnodeを用いて各種コマンドを実行してくれるので、切り替えを意識することがなくなります。

### といってもファイルを自分で書く必要はない

```
$ cd /path/to/project/root
$ nodenv local 12.12.0
```

これでそのディレクトリに `.node-version` ファイルを生成してくれ、次回以降このディレクトリ内での作業時には自動的にnodeのバージョンが切り替わります。

### `.gitignore_global` でignoreしておく

プロジェクトで固定、かつ、チームメンバーが `nodenv` を使っている前提であれば、プロジェクトのルートに `.node-version` ファイルをコミットしておいて、共有しておくのはとてもいいソリューションだと思いますが、諸々の事情でコミットできない場合もあると思います。そういう場合には、そのマシン全体でgitignoreできる `.gitignore_global` を使うのもひとつの手です。

```
$ cd ~
$ vi .gitignore_global
```

ただし、その後、他のプロジェクトで `.node-version` を使うとなった際にgitに入ってこなくなるので注意が必要です。

## おかしい時のチェック

### とりあえずバージョンは逐一確認してみる

```
node -v
```

### インストールされている場所も確認しておく

```
which node
```

例えば、↓こういうのが表示されるのはMacのデフォルトのnodeを使っている状態なので、 `nodebrew` にしろ `nodenv` にしろが動作している前提だとしたら、間違っている可能性が高いです。

```
/usr/local/bin/node
```

こういう場合、nodenvなどのセットアップが適切にできればそちらが使われますし、最悪この元の場所にインストールすることもできますから、**消しちゃって大丈夫**です。

### コマンドがみつからない系

```
* : command no found
```

とりあえず、下記で**ターミナルを再読み込みしてみたり、なんなら再起動**してみましょう。割とそれで解決することが多いはず。

```
exec $SHELL -l
```

それでもダメな場合は所謂「パスが通っていない」可能性もあるので、**インストール時に表示されていた内容を見直してみたり、再インストールする必要がある**かもしれません。
install complete的なメッセージが出ていても、もうひと手順あることが意外とあります。

## まとめ

やはり先にnodeを全部消すのがよいです。変に保険をかけず`node -v`でなにも出なくなるようにするのを優先した方が早かったと思います。（もしかすると`npm -v`も。）