web-dev-qa-db-ja.com

requirejsを使用すると、モジュールをロードすることなく、モジュールが定義されているかどうかを確認できますか?

オプションでモジュールを定義して、それをコードで使用できるようにしたいのですが。私が検討している特定の状況は、デバッグ/テスト環境にモック/スタブモジュールをロードすることですが、ライブに移行するときではありません。次に例を示します。

HTMLファイルでは、jsファイルはオプションでロードされます(疑似コード):

//index.cshtml
...
<script src="/Scripts/lib/require.js"></script>
<script src="/Scripts/app/service_user.js"></script>
<script src="/Scripts/app/real_service.js"></script>
#if DEBUG
<script src="/Scripts/app/mock_service.js"></script>
#endif

上記では、real_serviceとmock_serviceの両方をデバッグバージョンにロードする必要があります。

各モジュールはrequirejsを使用して定義されます。例:

//mock_service.js
define('mock_service', [], 
    function () {
        ...
    });

//real_service.js
define('real_service', [], 
    function () {
        ...
    });

次に、サービスを使用するときに、mock_serviceが定義されているかどうかを確認します。

//service_user.js
define(['require', 'real_service'], 
    function (require, real_service) {
        if (require.isDefined('mock_service')) { // 'isDefined' is what I wish was available
             var mock = require('mock_service');
             mock.init(real_service);
        }

        ...
    });

したがって、私の概念的な「isDefined」関数は、指定された名前(または名前?)が定義されているモジュールをチェックするだけです。次に、私のコードで、それが定義されている場合は、それを要求して使用できます。そうでない場合は、それでも問題ありません。

私にとって重要なことは、オプションのモジュールをロードする試みが行われないことです。 requireステートメントを試す/キャッチすることはできますが、サーバーからそれをロードしようとするため、それは望みません。

別のオプションは、常にロードするスタブを定義することです。そのため、必要なモックが常にあり、それが実際のものかどうかについて問い合わせることができますが、それも無駄に見えます。

Require.jsに深く関わっていて、この機能が必要であり、実装の戦略を練っている人はいますか?

よろしくお願いします、ロブ

35
WooWaaBob

デビッドウルフの答えはマークに近かったが、それは私のニーズを完全には満たしていませんでした。

問題は、requiredが非同期で要件を解決することです。そのため、私が指定した例では、Davidの提案require.defined('mock_service')を使用すると、falseが返されます。

これを調査したところ、別の関数specifiedが見つかりました。この例では、require.specified('mock_service')trueを返しますが、require('mock_service')を使用して参照を取得しようとすると、まだ解決されていないため失敗します。

幸い、コールバックバージョンのrequireを使用することで簡単に修正できます。まとめると、次のようになります。

if (require.specified('mock_service')) {
    require( [ 'mock_service' ], function (mock) {
         mock.init(real_service);
    });
}

@David Wolf-ありがとう、あなたの助けがなければそこにたどり着けなかっただろう。

46
WooWaaBob

私はこれを自分で探していましたが、requireグローバルには、モジュール名を取得してtrueまたはfalseを返す「定義済み」メソッドがあります。

// returns true
require.defined("my/awesome/defined/module");

// returns false
require.defined("not/yet/loaded");
62
David Wolf