😽

【Qiitaからの移行記事】nodenv管理下の npm で yarn を install した時に yarn の PATH が通らなかった

2022/09/18に公開

mac上で、 homebrew を使わずに anyenv 及び nodenv で node や npm をセットアップして yarn をインストールした時に、なぜか yarn の PATH が通らなかった。
Webを漁ってみたら、なんだか「よくわからんから yarn だけ brew でインストールした!」という解決策ばかりHITしたので、マシと思える解決策を探ってみた。

※ 2020-06-23 追記
当記事を書いた当初の結論よりも的確な解決方法をコメント欄にてご教示いただきましたので、結論を訂正しました。
手っ取り早く解決したい方は「結論」セクションをご覧ください。

yarn インストールまでの経過(準備操作)

$ git clone https://github.com/anyenv/anyenv ~/.anyenv
$ echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(anyenv init -)"' >> ~/.bash_profile
$ exec $SHELL -l
$ anyenv install --init
$ exec $SHELL -l
$ anyenv versions    # anyenv が動作することを確認
$ echo 'eval "$(anyenv init -)"' >> ~/.bash_profile
$ mkdir -p ~/.anyenv/plugins
$ git clone https://github.com/znz/anyenv-update.git ~/.anyenv/plugins/anyenv-update
$ git clone https://github.com/znz/anyenv-git.git ~/.anyenv/plugins/anyenv-git

$ anyenv install -l  # anyenv が扱えるモノを確認
$ anyenv install nodenv
$ exec $SHELL -l

$ nodenv install -l  # nodenv が扱えるモノを確認
$ nodenv install 10.21.0
$ exec $SHELL -l
$ nodenv global 10.21.0
$ npm -v             # npm が動作することを確認
$ npm install -g yarn
/Users/hogehoge/.anyenv/envs/nodenv/versions/10.21.0/bin/yarn -> /Users/hogehoge/.anyenv/envs/nodenv/versions/10.21.0/lib/node_modules/yarn/bin/yarn.js
/Users/hogehoge/.anyenv/envs/nodenv/versions/10.21.0/bin/yarnpkg -> /Users/hogehoge/.anyenv/envs/nodenv/versions/10.21.0/lib/node_modules/yarn/bin/yarn.js
+ yarn@1.22.4
added 1 package in 0.502s

$ yarn
bash: yarn: command not found

# ここで「なんで yarn の PATH が通ってない?」に至る。

本題

node や npm がシェルからどう見えてるか確認。

$ which npm
/Users/hogehoge/.anyenv/envs/nodenv/shims/npm

$ ls -la ~/.anyenv/envs/nodenv/shims/
total 24
drwxrwxr-x   5 hogehoge  staff  160  6  8 11:50 .
drwxrwxr-x  24 hogehoge  staff  768  6  8 11:54 ..
-rwxrwxr-x   1 hogehoge  staff  431  6  8 11:50 node
-rwxrwxr-x   1 hogehoge  staff  431  6  8 11:50 npm
-rwxrwxr-x   1 hogehoge  staff  431  6  8 11:50 npx

shims って何だわけ?

$ file /Users/hogehoge/.anyenv/envs/nodenv/shims/npm
/Users/hogehoge/.anyenv/envs/nodenv/shims/npm: Bourne-Again shell script text executable, ASCII text

bashスクリプトなのか。 npm の中身は...

$ cat /Users/hogehoge/.anyenv/envs/nodenv/shims/npm
#!/usr/bin/env bash
set -e
[ -n "$NODENV_DEBUG" ] && set -x

program="${0##*/}"
if [ "$program" = "node" ]; then
  for arg; do
    case "$arg" in
    -e* | -- ) break ;;
    */* )
      if [ -f "$arg" ]; then
        export NODENV_DIR="${arg%/*}"
        break
      fi
      ;;
    esac
  done
fi

export NODENV_ROOT="/Users/hogehoge/.anyenv/envs/nodenv"
exec "/Users/hogehoge/.anyenv/envs/nodenv/libexec/nodenv" exec "$program" "$@"

ほうほう、node は?

$ cat /Users/hogehoge/.anyenv/envs/nodenv/shims/node
#!/usr/bin/env bash
set -e
[ -n "$NODENV_DEBUG" ] && set -x

program="${0##*/}"
if [ "$program" = "node" ]; then
  for arg; do
    case "$arg" in
    -e* | -- ) break ;;
    */* )
      if [ -f "$arg" ]; then
        export NODENV_DIR="${arg%/*}"
        break
      fi
      ;;
    esac
  done
fi

export NODENV_ROOT="/Users/hogehoge/.anyenv/envs/nodenv"
exec "/Users/hogehoge/.anyenv/envs/nodenv/libexec/nodenv" exec "$program" "$@"

npm も node も中身一緒か。
コード見る限り yarn も同じもの用意すれば行けそうだな。

$ cp -a /Users/hogehoge/.anyenv/envs/nodenv/shims/{node,yarn}

$ yarn -v
1.22.4

PATH通った。

結論

nodenv 管理下でインストールした node関連ライブラリ所属のコマンドをシェルから直接呼びたかったら、shims/ 配下に上記のbashスクリプトをコマンド名で作成すれば良さそうね。

下記を実行することで nodenv管理下の shims が更新され、これにより yarn のパスが通ります。

$ nodenv rehash

※上述の「本題」で書いたことは、 「nodenv管理下の shims が更新される」 とは具体的に何がどうなることなのか、を追いかけた形になります。

Discussion