[npm & Bower] Node を Homebrew でインストールした場合でも npm をうまく利用したい(global install 編)

過去に断片的に調べて利用していたものの、色々と混乱したのであらためて再調査。

[markdown]
> * [npm: node.js のパッケージマネージャについて調べる | deadwood](https://www.d-wood.com/blog/2013/11/01_4974.html)

公式ドキュメントが詳しいため、通常は問題は起こらないのだと推測。

> * [01 – What is npm? | npm Documentation](https://docs.npmjs.com/getting-started/what-is-npm)

利用中につまずいた部分を中心に記す。

## 前提

タイトルの通り [Node.js](https://nodejs.org/en/) は [Homebrew](http://brew.sh/index_ja.html) でインストールされている。

> * [Node.js: Homebrew で node.js をインストールする | deadwood](https://www.d-wood.com/blog/2014/03/21_5852.html)

“`prettyprinted
% node -v
v5.2.0
% npm -v
3.5.2
“`

実体は下記に存在する。

“`prettyprinted
% ls -l /usr/local/bin |grep ‘npm@\|node@’ |awk ‘{print $9,$10,$11}’
node@ -> ../Cellar/node/5.2.0/bin/node
npm@ -> /usr/local/lib/node_modules/npm/bin/npm-cli.js
“`

## global install

`sudo` 付きでインストールする。

“`prettyprinted
% sudo npm install -g Package_name
“`

/usr/local/lib 以下に node_modules がインストールされる。

“`prettyprinted
% npm list -g –depth 0
/usr/local/lib
├── autoprefixer@6.1.2
├── bower@1.7.0
:
├── npm@3.5.2
├── stylestats@6.0.0
└── trash@3.4.0
“`

cli コマンドは /usr/local/bin 以下にシムリンクが作られている。

“`prettyprinted
% ls -l /usr/local/bin |grep ‘node_modules’ |awk ‘{print $9,$10,$11}’
bower@ -> ../lib/node_modules/bower/bin/bower
:
npm@ -> /usr/local/lib/node_modules/npm/bin/npm-cli.js
stylestats@ -> ../lib/node_modules/stylestats/bin/cli.js
“`

上記の内、`autoprefixer` と `trash ` については後述する。

## global update

`sudo` 付きでアップデートする。

“`prettyprinted
% sudo npm update -g
“`

### command not found 問題

グローバルにインストールしていた npm コマンドがアップデートによって利用できなくなる問題。

“`prettyprinted
% trash foo.txt
zsh: command not found: trash
“`

調べてみるとインストールするパッケージが変わっていたりしがち。
前述の例であれば `trash` や `autoprefixer ` が該当。
比較するとコマンドが存在しないことが分かる。

> * [rm の代替コマンド trash で安全にファイルを削除する | deadwood](https://www.d-wood.com/blog/2015/02/04_7389.html)
> * [sindresorhus/trash](https://github.com/sindresorhus/trash)
> * [CSS Lint の vendor prefix WARNING から Can I use, Autoprefixer, Compass の確認まで | deadwood](https://www.d-wood.com/blog/2015/01/31_7381.html)
> * [postcss/autoprefixer](https://github.com/postcss/autoprefixer)

## global uninstall

前述の問題を解消するために、例えば `trash` をインストールし直す。

“`prettyprinted
% sudo npm uninstall -g trash
% sudo npm install -g trash-cli
“`

### ENOENT: no such file or directory 問題

以下のコマンドで状況を確認するとエラーが表示される。

“`prettyprinted
% npm list -g –depth 0
/usr/local/lib
:
├── stylestats@6.0.0
├── error: ENOENT: no such file or directory, open ‘/usr/local/lib/node_modules/trash/package.json
└── trash-cli@1.2.0
npm ERR! error in /usr/local/lib/node_modules/trash: ENOENT: no such file or directory, open ‘/usr/local/lib/node_modules/trash/package.json’
“`

該当するディレクトリを調べると、ディレクトリが空の状態で存在する。
削除するとエラーが消える。
/usr/local/bin のシンボリックリンクはキレイに消えていた。

“`prettyprinted
% cd /usr/local/lib/node_modules
% sudo rm -rf trash
% npm list -g –depth 0
/usr/local/lib
├── bower@1.7.0
:
├── stylestats@6.0.0
└── trash-cli@1.2.0
“`

以前に Homebrew と /usr/local の権限の取り合い問題にもあたっていた。
どうもパーミッションの問題でディレクトリを消せなかったように見える(確証なし)。

> * [sudo npm -g update もしくは install でエラーが表示された場合の対処 | deadwood](https://www.d-wood.com/blog/2015/10/22_7640.html)
> * [brew doctor で Warning: /usr/local/** isn’t writable. とエラーが表示された場合の対処 | deadwood](https://www.d-wood.com/blog/2015/10/16_7637.html)

## Homebrew ユーザーは node_modules の場所を変更する

前述のパーミッションの問題も出てくるため、Homebrew ユーザーは node_modules の場所を変更しようぜということになる。

> * [Instructions on how to fix npm if you’ve installed Node through Homebrew on Mac OS X or Linuxbrew](https://gist.github.com/DanHerbert/9520689)

$HOME にディレクトリを作成して、そこに配置させる。
公式ドキュメントにも変更方法が記載されている。

> * [03 – Fixing npm permissions | npm Documentation](https://docs.npmjs.com/getting-started/fixing-npm-permissions)
`$HOME/.npmrc` に設定を追加し、

“`prettyprinted:~/.npmrc
prefix = ~/local/lib/node_modules
“`

shell にもパスを通す。

“`prettyprinted:~/.zshenv
# for npm
if [ -d $HOME/local/lib/node_modules/bin ]; then
export PATH=$PATH:$HOME/local/lib/node_modules/bin
fi
“`

> * [transitive.info – npm の設定(Ubuntu 12.10)](http://transitive.info/2013/01/16/npm-nodejs-ubuntu-1210/)

### あたらしい node_modules をインストールする

npm をあたらしい設定配下に再インストールする。
`sudo` は必要ない。

“`prettyprinted
% which npm
/usr/local/bin/npm
% npm install -g npm bower
/Users/****/local/lib/node_modules/bin/npm -> /Users/****/local/lib/node_modules/lib/node_modules/npm/bin/npm-cli.js
/Users/****/local/lib/node_modules/lib
└─┬ npm@3.5.2
:
“`

### 以前の node_modules を削除する

/usr/local/lib 以下の node_modules を削除する。

“`prettyprinted
% sudo rm -rf /usr/local/lib/node_modules
“`

/usr/local/bin 以下のシムリンクを削除する。

“`prettyprinted
% cd /usr/local/bin
% ls -al ./ |grep ‘../lib/node_modules’ |awk ‘{gsub(/@/,””);print $9}’ |xargs rm -i
“`

### 確認

ログインし直した後に確認。

“`prettyprinted
% which npm
/Users/****/local/lib/node_modules/bin/npm
% npm bin -g
/Users/****/local/lib/node_modules/bin
% npm list -g –depth 0
/Users/****/local/lib/node_modules/lib
├── bower@1.7.1
└── npm@3.5.2
“`

## 結論

– .npmrc に設定を追加し、node_modules のインストール場所を変える。
– node_modules/bin に path を通す。

公式とあわせて、こちらが参考になった。

> * [A Beginner’s Guide to npm — the Node Package Manager](http://www.sitepoint.com/beginners-guide-node-package-manager/)

続きます。

> * [Node を Homebrew でインストールした場合でも npm をうまく利用したい(local install 編) | deadwood](https://www.d-wood.com/blog/2015/12/15_7728.html)

## 補遺

なお Node.js は [nodebrew](https://github.com/hokaccha/nodebrew) でもインストールできる。

> * [Node.js: nodebrew で node.js をインストールする | deadwood](https://www.d-wood.com/blog/2013/10/30_4963.html)
> * [Node.js: nodebrew でのバージョンアップ手順のメモ | deadwood](https://www.d-wood.com/blog/2013/12/12_5114.html)

この場合、node_modules は `~/.nodebrew` 以下に配置される。
そのため global install 時に `sudo` が必要なかったり、cli コマンドのパスも自動で通ったりするようだ。
nodebrew を使うと、このあたりの悩みがなくなりそうな気もする(未検証)。

### npm command

> * [npm: コマンドの補完機能を有効にする | deadwood](https://www.d-wood.com/blog/2014/08/22_6699.html)
> * [npm: list コマンドの depth を調整する | deadwood](https://www.d-wood.com/blog/2015/10/30_7653.html)
[/markdown]