npm install が EACCES(permission denied)で失敗する
グローバル install で /usr/local や /usr/lib への書き込み権限が無いと EACCES になる。
sudo に頼らず npm の prefix をユーザー領域に張り直すか、nvm / fnm で Node 自体を入れ直すのが安全策。
#npm#permission#eacces#install#nvm
公開:
要約
npm install -g で EACCES: permission denied が出るのは、グローバル prefix が システム所有のディレクトリ を指しているため。sudo npm で逃げると ~/.npm の所有権が root に汚染され、後の通常 install まで巻き添えで失敗するようになる。
安全策は prefix をユーザー領域に張り直す か、nvm / fnm / volta で Node 自体をユーザー領域に入れ直す こと。
よくある原因
- prefix がシステム領域:
npm config get prefixの出力が/usr/localなど root 所有を指す - sudo install の副作用: 過去に
sudo npm i -gを打ち、~/.npmの所有権が root になっている - OS パッケージ製の Node: apt / yum / Homebrew で入れた Node はシステム配下に書き込もうとする
- 共有 node_modules: 別ユーザーで作られたディレクトリに今のユーザーで書き込もうとしている
解決策
1. prefix をユーザー領域に張り直す
mkdir -p ~/.npm-global
npm config set prefix '~/.npm-global'
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
npm install -g <pkg>公式の手順 に沿った最小構成。npm config get prefix で反映を確認する。
2. nvm / fnm / volta で入れ直す
# nvm の例
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
nvm install --lts
nvm use --ltsホームディレクトリ以下に Node が入るため、グローバル install もすべて書き込み権限のある場所に向く。fnm / volta も方針は同じ。
3. キャッシュの所有権を戻す
sudo chown -R $(whoami) ~/.npm過去に sudo を踏んでしまった場合の応急処置。
これを忘れると新 prefix に切り替えても EACCES が再発することがある。
4. sudo install を巻き戻す
sudo npm uninstall -g <pkg>
npm install -g <pkg> # 新 prefix に入れ直す以後 sudo npm を使わない方針に切り替える。
grep で履歴に残っていないかも確認しておく。