必要な引数を渡す(モジュールのロード時)


113

requireを使用してモジュールをロードするときに引数を渡すことは可能ですか?

ログイン機能を提供するモジュールlogin.jsがあります。データベース接続が必要であり、すべてのモジュールで同じデータベース接続を使用したい。次に、データベース接続を指定できる関数login.setDatabase(...)をエクスポートします。これは問題なく機能します。しかし、モジュールをロードするときに、データベースとその他の要件を渡します。

var db = ...
var login = require("./login.js")(db);

私はNodeJSでかなり新しく、通常JavaとSpring Frameworkを使用して開発しているので、はい...これはコンストラクターインジェクションです:)上記で提供したコードのようなことを行うことは可能ですか?


この質問への回答もご覧になることをお勧めします。私の回答で指摘したように、一般的なイディオムはappオブジェクトを必要なモジュールに渡すことです。
David Weldon、

このすべての引数をdbに渡す代わりに、シングルトン実装を使用して、必要に応じてdb.getInstance()を呼び出すことができます。
wulfgarpro 2015年

回答:


236

この回答でのあなたのコメントに基づいて、私はあなたがしようとしていることを次のようにします:

module.exports = function (app, db) {
    var module = {};

    module.auth = function (req, res) {
        // This will be available 'outside'.
        // Authy stuff that can be used outside...
    };

    // Other stuff...
    module.pickle = function(cucumber, herbs, vinegar) {
        // This will be available 'outside'.
        // Pickling stuff...
    };

    function jarThemPickles(pickle, jar) {
        // This will be NOT available 'outside'.
        // Pickling stuff...

        return pickleJar;
    };

    return module;
};

私はほとんどすべてのモジュールをそのように構成しています。私にとってはうまくいくようです。


あるapp引数が必要か、私はそれをOMMITことができますか?私のモジュールはこのアプリの引数を明示的に使用しませんが、node.jsが内部的なことで必要かどうかはわかりません。それは大丈夫だ場合は、私のモジュールの宣言は次のようになりますmodule.exports = function (db) {
ユリシーズ・アウベス

これはExpressアプリに固有なので、絶対に必要ではありません。
floatingLomas

Pythonで直列化機構がピクルスと呼ばれ@floatingLomas:stackoverflow.com/questions/11218477/...
SadSeven

1
では、モジュールを数回参照するとどうなるでしょうか。1つ目require(mymodule)(myargs)は、使用するモジュールを提供します。ただし、別のモジュールから別の場所で参照している場合はどうなりますか?基本システムではキャッシュが含まれているように見えますが、このシステムでは、への後続の呼び出しでキャッシュがベアジェネレーターメソッドを返し、require()argsを渡した場合require()(someargs)、別のモジュールが返されます...おそらく私は欠落しています何か
トムH

2
@TomHその場合は、キャッシュする必要があります。これを行うにはvar module;、exports関数の外部にアクセスし、次に入ったらすぐに、moduleが既に定義されているかどうかを確認し、定義されている場合はそれを返します(定義されていない場合は初期化します)。それは理にかなっていますか?
floatingLomas

37

これがまだ人々に役立つかどうかはわかりませんが、ES6を使用すると、クリーンで便利な方法を見つけることができます。

class MyClass { 
  constructor ( arg1, arg2, arg3 )
  myFunction1 () {...}
  myFunction2 () {...}
  myFunction3 () {...}
}

module.exports = ( arg1, arg2, arg3 ) => { return new MyClass( arg1,arg2,arg3 ) }

そして、あなたはあなたの期待される行動を得る。

var MyClass = require('/MyClass.js')( arg1, arg2, arg3 )

32

はい。あなたにはlogin、モジュール、ちょうど取る単機能エクスポートdb引数としてを。例えば:

module.exports = function(db) {
  ...
};

1
私はこれを試しました。login.js module.exports = function(app,db) { ... } module.exports.auth = function(req,res) { ... authentication stuff } では「匿名」関数を呼び出して変数appdb変数を設定しますが、これを行うと、アプリケーションでauth関数が見つかりません。何が悪いのですか?無名関数を削除すると、そのauth関数に再びアクセスできるようになります。
Andreas Selenwall 2012年

JavaScriptのすべてのようにexports、オブジェクトです。プロパティを割り当てることができます(複数のエクスポート)、または値に割り当てることができます。エクスポートを関数に割り当てたようですが、エクスポートに割り当てた関数のプロパティとしてauthを割り当てました。したがって、var auth = require("./login.js").auth意図したものとは異なる可能性があることを行う必要があります。元の質問のパターンを使用する場合は、単一のエクスポート値を使用するのがおそらく最善です。それでも問題が解決しない場合は、要点を掲載することをお勧めします。
David Weldon、2012年

1
これをもう一度読んだ後authは、exportsオブジェクトのプロパティとして割り当ててから、後でモジュールにexports関数に割り当てた(つまり、前の割り当てをオーバーライドした)ように思えます。割り当ての順序を逆にすると、auth期待どおりに関数にアクセスできるはずです。繰り返しになりますが、実際にコードを見ずに見分けることは困難です。
David Weldon、

1
あなたの助けをたくさんありがとう。require( 'login')。authでまさにあなたが目指していたのは、私が理解していなかったことです。とには違いはvar login = require('login')ありませんでしたvar login = require('login')(app)が、大きな違いがあり、返された無名関数には魔法がありません。それは単なる別の関数/オブジェクトです。module.exports.authanomymous関数は、を持つ代わりに、(他のものの中で)auth関数を返しますreturn { auth: authFunction, login: loginFunction}。だから今はうまくいきます。ありがとう。
Andreas Selenwall、2012年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.