web-dev-qa-db-ja.com

Node.jsの個別のモジュールに共通の変数を渡す最良の方法は何ですか?

メインアプリと認証アプリのモジュールとして、個別のルーターファイルを使用します。変数(dbクライアント)をルーターに渡す最良の方法を取得できません。私はそれをハードコーディングしたり、渡したりしたくありません:

module.exports = function(app, db) {

たぶん、シングルトンレジスタを使用するか、グローバルdb変数を使用するのが最善の方法ですか?

デザインパターンの経験は何ですか?どちらの方法が最適で、なぜですか?

59
Serg

私は、依存性注入を使用して、物事を渡す、最高のスタイルにすることを発見しました。それは確かにあなたが持っているように見えるでしょう:

_// App.js
module.exports = function App() {
};

// Database.js
module.exports = function Database(configuration) {
};

// Routes.js
module.exports = function Routes(app, database) {
};

// server.js: composition root
var App = require("./App");
var Database = require("./Database");
var Routes = require("./Routes");
var dbConfig = require("./dbconfig.json");

var app = new App();
var database = new Database(dbConfig);
var routes = new Routes(app, database);

// Use routes.
_

これには多くの利点があります。

  • require("databaseSingleton")またはさらに悪いことに_global.database_を呼び出すファイルの途中で依存関係を隠すのではなく、システムを明確な依存関係を持つコンポーネントに分離することを強制します。
  • 単体テストを非常に簡単にします。Routesを単独でテストする場合は、偽のappおよびdatabase paramsを挿入し、Routesコードのみをテストできます。
  • すべてのオブジェクトグラフの配線を1つの場所、つまり構成ルート(この場合はアプリのエントリポイントである_server.js_)にまとめます。これにより、システム内ですべてがどのように組み合わされるかを確認するための単一の場所が提供されます。

私が見たこのことについてのより良い説明の1つは、 Mark Seemanとのインタビュー 、素晴らしい本の著者です .NETでの依存性注入。 JavaScript、特にNode.jsにも同様に適用されます。requireは、単なるモジュールシステムではなく、古典的なサービスロケーターとしてよく使用されます。

108
Domenic

Dbインスタンスと、「シングルトン」のようにグローバルに使用する必要がある他のもので設定ファイルを作成することをお勧めします。

たとえば、redis dbクライアントにsettings.jsがあります:

var redis = require('redis');
exports.redis = redis.createClient(6379, '127.0.0.1');

そして、他の複数のモジュールにそれを含めます:

var settings = require('./settings');
setting.redis.<...>

それを含む多くの場合、私は常にdb接続の1つのインスタンスを持っています。

2
akaravashkin

依存性注入フレームワークを使用する場合、モジュールを接続するためのすべての定型コードを保存できます

この回答 そのうちのいくつかをリストします。 ここではより単純なDIフレームワーク も作成しました。

EDIT:以下は、ページが変更された場合の回答のコピーです


requireは、Node.jsで依存関係を管理する方法であり、確かに直感的で効果的ですが、制限もあります。

私のアドバイスは、Node.jsで現在利用できるDependency Injectionコンテナのいくつかを見て、その長所/短所を把握することです。それらのいくつかは次のとおりです。

ほんの数例を挙げます。

本当の問題は、単純なrequireと比較して、Node.js DIコンテナーで何を達成できるかということです。

長所:

  • テスト容易性の向上:モジュールは依存関係を入力として受け入れます
  • 制御の反転:アプリケーションのメインコードに触れることなくモジュールを配線する方法を決定します。
  • モジュールを解決するためのカスタマイズ可能なアルゴリズム:依存関係には「仮想」識別子があり、通常はファイルシステム上のパスにバインドされていません。
  • 拡張性の向上:IoCおよび「仮想」識別子によって有効になります。
  • 可能な他の派手なもの:
    • 非同期初期化
    • モジュールのライフサイクル管理
    • DIコンテナ自体の拡張性
    • より高いレベルの抽象化(AOPなど)を簡単に実装できます

短所:

  • Node.jsの「エクスペリエンス」とは異なります。requireを使用しないことは、Node考え方から逸脱しているように感じられます。
  • 依存関係とその実装との関係は、必ずしも明示的ではありません。依存関係は実行時に解決され、さまざまなパラメーターの影響を受ける場合があります。コードの理解とデバッグがより難しくなります
  • 起動時間が遅い
  • 成熟度(現時点):現在のソリューションはどれも本当に人気がないため、あまり多くのチュートリアルもエコシステムも戦闘テストもされていません。
  • 一部のDIコンテナは、BrowserifyやWebpackなどのモジュールバンドラーとうまく機能しません。
1
Gaafar

それは完全に時代遅れですが、スクリプトでglobalを使用できます:

 global.foo = new Foo();

別のスクリプトで:

 foo.bar();

既存の定数を使用することもできます:

 Object.foo = new Foo();

そしてここ :

 Object.foo.bar();
0
Vinz243