グローバルでインストールしたパッケージを node
で使おうとした際に
Uncaught Error: Cannot find module
となりました。
# グローバルで socket.io-client を使えるように
$ npm install -g socket.io-client
# nodeから使ってみようとするとエラー
$ node
> var io = require('socket.io-client')
Uncaught Error: Cannot find module 'socket.io-client'
・・・
グローバルでインストールしたパッケージを使えるようになると、何かと便利になりそうな感じがしたので使えるようにしてみました!
検証した環境
1 | node | 16.15.0 |
2 | npm | 8.6.0 |
3 | yarn | 1.22.18 |
グローバルでインストールしたパッケージをnodeで使えるようにする
結論としては、
環境変数 NODE_PATH
にパスを通すことで読み込めるようになります!
最終的なイメージとしては.zshrcなどに以下のように記載します。
.zshrc
# 通したいパスを記載する(デフォルトのものに追加される)
# 以下は npmとyarnそれぞれのグローバルでインストールしたパッケージを読み込む
export NODE_PATH="${HOME}/.config/yarn/global:/opt/homebrew/lib/node_modules"
順番に上記のように設定した背景を記載していきます。
node実行時に読み込まれるパスについて
まずnodeコマンド実行時に読み込むパスの一覧の確認の仕方が以下になります
# node実行後に global.module.paths
$ node
> global.module.paths
[
'/Users/yuu/repl/node_modules',
'/Users/yuu/node_modules',
'/Users/node_modules',
'/node_modules'
・・・
]
npm・yarnでグローバルインストールした際のパスについて
npm・yarnそれぞれglobalで読み込んでいるライブラリのパスは以下のコマンドで確認出来ます
npm
# npmのグローバルのインストール先
$ npm root -g
/opt/homebrew/lib/node_modules
yarn
# yarnのグローバルのインストール先
$ yarn global dir
/Users/yuu/.config/yarn/global
そして先程のglobal.module.paths
に上記のパスがないため、
nodeコマンド内では使えない、というのが起きている事象。
あとは、これらのパスが読み込めるようにしてあげます。
NODE_PATHを設定
最初に結論として書いた通り、
node
は NODE_PATH
に記載したパスのモジュールを読み込んでくれます。
$ node -h
・・・
NODE_PATH ':'-separated list of directories prefixed to the module search path
そしてnodeのhelpに記載があるように :
で複数指定する事が出来ます。
私はnpm・yarnどちらでもグローバルインストールしてしまう事があるので両方指定しました。笑
.zshrc
export NODE_PATH="${HOME}/.config/yarn/global:/opt/homebrew/lib/node_modules"
あとはnodeで使えるようになっているかを確認します
[yuu]$ node
> global.module.paths
> [
'/Users/yuu/repl/node_modules',
'/Users/yuu/node_modules',
'/Users/node_modules',
'/node_modules',
'/Users/yuu/.config/yarn/global', # <=追加されてる!
'/opt/homebrew/lib/node_modules', # <=追加されてる!
'/Users/yuu/.node_modules',
'/Users/yuu/.node_libraries',
'/opt/homebrew/Cellar/node/18.0.0/lib/node'
]
$ node
> var io = require('socket.io-client')('http://127.0.0.1:3000');
> io.emit("message", "test")
<ref *1> Socket {
connected: true,
・・・
エラー出ずに使えるようになりました!