3

実行時にrequirejs(またはAMDローダー)の設定を変更することは可能ですか?

例として、2 つのログ モジュールがあります。1 つは単に console.log をラップするモジュールで、もう 1 つはサーバーにログを記録するモジュールです。require(['log'], function(log) { ... });モジュールが単純に log ( ) を要求し、使用しているロガーを気にしないようにしたいと思います。

require のメイン構成で「ログ」をパッケージとして設定できますが、これは正常に機能します。しかし、いくつかの条件に基づいて main.js でこのオプションを設定することをお勧めします。何かのようなもの:

if( ... ) {
    require.config({
        packages: [
            { name: 'log', location: 'app/base/utils/consolelog' }
        ]
    });
}

しかし、これはうまくいかないようです。これを行う方法はありますか、または依存性注入フレームワークとしてrequirejsの機能をプッシュしていますか?

乾杯

4

1 に答える 1

4

依存性注入フレームワークの一般的なインストルメンテーションは、実行時に解決する依存性コンテナーの種類を構成するための1つの簡単なアプローチがあり、アプリケーションの存続期間を通じて1回だけ構築され、静的に保たれることです。

これは特に、アプリケーションのある時点で依存関係が変更される可能性がないような場合に発生しないようにするために行われます。アプリケーションソースの1つまたはすべてが、コンテナに名前を付けるのではなく、コンテナからの依存関係の一部または一部を消費する前に許可を求める必要があるというこの概念を持つことは、多くの欠点があるひどい考えの1つです。主な欠点は、あなたが知っていることです。それ以外の場合、の参照は、accounts.all().each().withdraw(billing.MONTHLY_SERVICE_FEE).return()明白な理由がない限り、どの時点でも異なる動作をする可能性があります。Accounts変更しnew Accounts().all()てアカウントを返さなかった場合、または突然billing.MONTHLY_SERVICE_FEE変更して一部のアカウントにXの金額を請求し、他のアカウントにYを請求した場合は問題になります。

したがって、簡単な答えは「いいえ」です。RequireJSを動的に構成することはできません。RequireJSは常にモジュールを1回だけロードするため、コールバックの戻り値は常に静的オブジェクトです。または、モジュールソースを見ると、define()その存続期間中1回だけ評価されることがわかります。資料。

実行時にオブジェクトの特定の実装を抽象化する方法に対するいくつかの非常に単純なアプローチがあります。同一のパブリックインターフェイスを持つオブジェクトを返すコールバックを使用して複数のモジュールを作成するだけですが、動作が異なり、静的または動的にどちらを返すかを解決します。

// core/logging/base.js
define(function() {
  var static;
  var base =  {
      _log: undefined,
      create: function(name) {},
      // ..
  }

  return base;
});

// core/logging/client.js
define(function(['core/logging/base'], function(base) {
  var client = extend(base, {_log: console.log});
  return client;
});

// core/logging.js
define(['core/logging/server', 'core/logging/client', 'core/conf/settings'], 
  function(server, client, environment) {
  if(settings.LOGGER === 'server') {
    return server;
  } else {
    return client;
  }
};

// app/foo.js
define(['core/logging'], function(logging) {
  var log = logging.createLog('foo');
  log.info('bar');
  // > INFO foo: bar
  // or...
  // POST http://server/log {type: 2, name: 'foo', message: 'bar'}
}

このようなサポートを設計する方法にはいくつかのアプローチがありますが、これはシンプルで魅力的であり、特定のケースで機能します。一般に、この解決はモジュール内で静的に実行することも、ゲッター関数を介して任意のブロックで動的に実行することもできます。モジュールのコールバック自体も、オブジェクトだけでなくコンストラクターまたは関数を返す可能性があります。

于 2013-02-14T19:21:34.333 に答える