複数のNode.jsがインストールされてしまっている問題
挨拶
こんにちは、T4D4です。
先日Node.jsのバージョンを気にする機会がありバージョンを確認したら設定している筈のバージョンとnode -vで表示されるバージョンが一致しなかったので調べた結果Node.jsが重複してインストールされているコトが発覚したので備忘録的な感じで書きます。
そもそもの発覚までの流れ
先日、夏休みなのでインターンをしようと某社にJoinしたので最初に環境構築が必要になりました。そこでりどみの手順に従い環境構築を進めていたらエラーが出て、解決策を考えた結果、詳細を省くとNode.jsのバージョンに問題がある
可能性に辿り着きました。そしてまずnode -vで今呼ばれているNode.jsのバージョンを確認するとv22.7.0と返ってきました。その後nでNode.jsのバージョン管理をしているのでn経由でインターン先の方(当然エラーが出ていない)が使用していたのと同じv20.9.0を入れて20.9.0を使用するように設定しました。しかし、設定後に問題無く設定が完了したか確認する為にnode -vを実行したところなんと変わらずv22.7.0と返ってきました。
重複しているNode.jsの確認
想定とは異なる結果が返ってきてnode -vで呼ばれるNode.jsがn経由で入れたNode.jsではない可能性に思い至ったったのでまず、which nodeでnodeのパスを確認しました。すると、/home/linuxbrew/.linuxbrew/bin/node
と返ってきました。nでインストールしたなら/usr/local/n/versions/node/[version]/bin/node
([version]はNode.jsのバージョンが入る)となる筈であること。そして、/home/linuxbrew/.linuxbrew/bin/
はpathの名前からわかるようにlinuxでのbrew経由でインストールしたパッケージの配置場所だと考えられます。これらの事柄から僕の環境にはn経由でインストールしたNode.jsと別にbrew経由でインストールされたNode.jsが存在していて普段はそちらが使われていることが明らかになりました。
解決策
解決策は簡単でbrew経由でインストールしたNode.jsのバージョン管理は面倒そうなのでbrew uninstall nodeでアンインストールしようとしました。しかし、直前でなぜbrew経由でもNode.jsがインストールされているのかを考えてみました。その結果、他のパッケージをbrew経由でインストールした時に依存関係に要求されて一緒にインストールされた可能性へと思い至りました。
実際、brew info node
を実行した結果、案の定いくつかのパッケージの依存関係に加えられていました。そこで安易にアンインストールすることで解決を図るのではなく、他の解決策を探すことにしました。
解決策2
他の解決策として、システムで呼びだすNode.jsを簡単に切り替えることができるようにし、乗り切るという少し強引な気がするアイディアを思いついたので実行することにしました。具体的には以下のようなシェルスクリプトを書きました。
#!/bin/bash
# 現在のNode.jsのパスを取得
current_node_path=$(which node)
echo "現在使用しているNode.jsのパスは $current_node_path です"
# Homebrew経由のNode.jsのパス
brew_node_path="/home/linuxbrew/.linuxbrew/bin/node"
# n経由のNode.jsのパスパターン
n_node_path_pattern="/usr/local/n/versions/node/*/bin/node"
# current_node_pathがHomebrew経由のパスか確認
if [ "$current_node_path" = "$brew_node_path" ]; then
# nの方に切り替える
export PATH="/usr/local/n/versions/node/20.9.0/bin:$PATH"
current_node_path=$(which node)
echo "HomebrewのNode.jsからnのNode.jsに切り替えました。現在のnodeのパスは $current_node_path です"
elif [[ $current_node_path == $n_node_path_pattern ]]; then
# Homebrewの方に切り替える
export PATH="/home/linuxbrew/.linuxbrew/bin:$PATH"
current_node_path=$(which node)
echo "nのNode.jsからHomebrewのNode.jsに切り替えました。現在のnodeのパスは $current_node_path です"
else
# エラーメッセージを表示して終了
echo "エラー: 現在のNode.jsのパスが認識できません。"
exit 1
fi
簡単に解説すると、まず現在のパスを取得。次に取得したパスがbrew経由のパスかを確認。trueならn版に切り替え、falseならパスがn経由のパスかを確認。ここでtrueならbrew版に切り替え、ここもfalseだったら何かおかしいのでエラー文投げて終了。となっています。シェルスクリプトをほとんど書いた事がないので8割GitHub Copilotに投げて書いてもらいましたw
おわりに
実は最初に環境構築をしていた時はインターン先の方とコワーキングスペースで一緒に作業していて閉まるまで時間がありませんでした。なので解決策1を実行し、Node.jsのバージョン問題を強引に解決し、最初の問題がNode.jsのバージョンを変えれば解決することを確認した後にbrewでNode.jsを再インストールして元に戻すという力業を実行してしまいましたw
Discussion