2016-10-08 8 views
0

ノードJSとExpressモジュールを使用してWebサーバーをセットアップしました。次のように私のコードは次のとおりです。ノードJSのrequire()を使用したスコープの問題

ファイルツリー:

/src 
| 
+-- server.js 
+-- /app 
    | 
    +-- routes.js 

server.js

// set up ====================================================================== 
var express = require('express'); 
var app  = express(); 
var mongoose = require('mongoose'); 

...

// configuration =============================================================== 
mongoose.connect(configDB.url); 

...

// routes ====================================================================== 
require('./app/routes.js')(app, passport); 

// launch ====================================================================== 
app.listen(port); 

routes.js

module.exports = function(app, passport) { 
     app.get('/some-route', function(req, res) { 
      // this line bugs out 
      var User = mongoose.model('User', userSchema); 
     }); 
    }; 

私の質問:mongoose.model()でroutes.jsを呼び出す

は、次のエラーがスローされます

ReferenceError:mongoose is not defined

なぜこの文脈ではmongooseは、routes.jsが含まれているserver.jsファイルに含まれていないのですか?私はroutes.jsで再びmongooseを要求する必要がありますか?私はここで何が欠けていますか?

答えて

1

モジュール内で定義された変数は、そのモジュールに対してのみローカルです。彼らはそのモジュールであなたがrequire()である他のモジュールの範囲にはありません。そのため、mongooseはあなたのルートモジュールには分かりません。 require()操作では、呼び出し元のモジュールにコードが正しく挿入されません。代わりに、そのコードをディスクからロードし、それをそれ自身の関数に挿入し、その関数を呼び出します。これにより、ロードされたモジュールごとに独立したスコープが与えられます。現在のスコープには挿入されません。路線で再びマングースモジュールで

  1. Require():このような場合には

    は、あなたはいくつかの選択肢があります。これは、ルートモジュールを必要に応じて必要に応じて再利用することができるようになるため、可能な場合には一般的に好まれます。

  2. apppassportのように、ルートコンストラクタと共有したいオブジェクトを渡します。この方法は、他のモジュールが必要とする項目が単なるモジュールのロード結果ではない場合に適しています。たとえば、appは、コンストラクタ関数を呼び出した結果です。したがって、別のモジュールが同じappインスタンスを使用する唯一の方法は、渡すことです。

  3. ルートに情報を要求するために他のモジュールを呼び出すことができます。たとえば、appオブジェクトをルートに渡したので、mongooseオブジェクトをappオブジェクトのプロパティとして配置して、そのように参照できるようにするか、appオブジェクトにメソッドを追加して取得することができますメソッド呼び出しこの場合

mongooseだけでキャッシュされたモジュールであることから、それはおそらく、再びちょうどrequire()それを最も理にかなっているが、上記の3つの方法のいずれか1つが動作します。

+0

私は正しく理解しています。 1番目のケースでは、mongooseモジュールがキャッシュされ、追加の負荷が発生しませんか? – matthiasdv

+1

@matthiasdv - はい、ノードはすべてのモジュールをキャッシュするので、2度目に要求すると、キャッシュされたモジュールハンドルだけが返されます。新しいコードをロードしたり実行したりすることはありません。 – jfriend00

1

ファイルに含まれているモジュールは、別のファイルには表示されません。あなたは彼らがこのファイルのコンテキスト内に定義されているファイル内で定義

https://nodejs.org/api/globals.html

他のすべてのオブジェクト/変数を:ここでは、作成したすべてのモジュールで使用可能なグローバルオブジェクトのリストを見つけることができます。そうしないと、他のファイルの他の変数を上書きしてプロジェクト内に混乱を生む変数に大きな問題が生じる可能性があります。すべてのコードとそこに定義されているすべてのコードを含む関数のようなファイルは、グローバル名前空間では使用できないと考えることができます。

あなたの場合、必要なファイルにはrequire('mongoose')が必要です。これは、データベースとの既存の接続を維持できるように構築されています。