Nodejsのrequestライブラリが非常によくできているので、クローリングで使い倒していたら、サーバー環境を変えた時に問題が発生。
インストールしているのに、下記の様なエラーがでた。
$ node hoge.js
module.js:472
throw err;
^
Error: Cannot find module 'request'
at Function.Module._resolveFilename (module.js:470:15)
at Function.Module._load (module.js:418:25)
at Module.require (module.js:498:17)
at require (internal/module.js:20:19)
at Module._compile (module.js:571:32)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:488:32)
at tryModuleLoad (module.js:447:12)
※hoge.jsの中でrequestライブラリを使っていますが、内容は割愛します。
そして、この事象に悩まされているエンジニアも多いという事実が、ググって判明しました。
Request問題の解決方法サイト
「global.module.paths」での検索結果・・・
node.js のrequire先pathにnpm -gでグローバルインストールしたのものを登録する
Node.jsで、存在するはずのmoduleがrequireでエラーになることについて
グローバルにインストールしたnode moduleがnot foundになる時の対処
node.jsのモジュール・パス
もっと沢山でるのですが、検索内容にrequestというキーワードが入っていないにも関わらず、これらのサイトは、すべてrequestのアクセスエラーでほぼ同じ内容でした。
原因
requestに関わらず、nodejsの仕様は、node_modulesというフォルダにライブラリが格納されるのですが、サーバー内の固定フォルダではなく、いくつかの環境に適合できる様になっている為、今回の不具合が発生しているようです。
基本的には、-gで指定する「グローバル環境」と、無指名の「ローカル環境」なのですが、システム側で複数のフォルダを対象にしている事が以下のコマンドからわかります。
$ node -e "console.log(global.module.paths)"
www-data@debian:/var/www/html/smartir$ node -e "console.log(global.module.paths)"
[ '/var/www/html/node_modules',
'/var/www/node_modules',
'/var/node_modules',
'/node_modules' ]
そして、これらのフォルダのほとんどが存在しない階層になっていて、なんとも行けていない設計なのがわかってしまいました。
他サイトで紹介されている解決方法と問題点
上記サイトの中で、解決方法として紹介されているのが、以下の手順。
## NODE_PATHの環境変数を確認
$ echo $NODE_PATH
## 環境変数になにも登録されていなければ、設定
$ export NODE_PATH=`npm root -g`
確かにこの操作で、ちゃんとrequestモジュールが使える様になりました。
・・・が、実はこの状態のままで、サーバーを再起動すると、export情報は消えてしまいます。
起動時に自動的にexportを実行してくれるバッチを作らないといけないのですが、サーバー環境やユーザー設定ごとに、めんどくさい設定をするのが嫌だったので、もっと簡単な解決方法がないか試してみたところ・・・見つけました。
もっと簡単な解決方法で解決
環境変数を通してあげるという基本的な対応もいいのですが、そもそもnpm環境変数に登録されているパスが存在しないという事実を逆に利用して、存在しないパスに、インストールされているパスに対してシンボリックリンクを作ってあげればいいという事です。
具体的には、以下の手順です。
## 1. リンク一覧の確認
$ node -e "console.log(global.module.paths)"
## 2. 存在しない事を確認
$ ls /node_modules
ls: /node_modules にアクセスできません: そのようなファイルやディレクトリはありません
## 3. 対象パスを取得
$ npm root -g
/usr/local/lib/node_modules
## 4. シンボリックリンクを作成
$ ln -s /usr/local/lib/node_modules /node_modules
上記設定をすると、問題なくモジュールも使えるし再起動しても、再設定の必要もありません。
requestエラーが出る環境の際に最初に確認してからこの設定をしてあげるといいようですね。
0 件のコメント:
コメントを投稿