グローバルインストールしたパッケージがnodeで使えない時の対処法

投稿日
グローバルインストールしたパッケージがnodeで使えない時の対処法

グローバルでインストールしたパッケージを 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を設定

最初に結論として書いた通り、

nodeNODE_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,
  ・・・

エラー出ずに使えるようになりました!

プロフィール画像
Yuki Takara
都内でフリーランスのエンジニアをやってます。フロントとアプリ開発メインに幅広くやってます。