web-dev-qa-db-fra.com

Avec requirejs, est-il possible de vérifier si un module est défini sans tenter de le charger?

Je souhaite pouvoir éventuellement définir un module puis l'utiliser ou non dans mon code. La situation particulière que j'envisage est le chargement de modules fictifs/stub dans l'environnement de débogage/test, mais pas lorsque je suis en ligne. Voici l'exemple:

Dans le fichier html les fichiers js seraient éventuellement chargés (pseudo code):

//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

Dans ce qui précède, real_service et mock_service doivent être chargés dans la version de débogage.

Chaque module serait défini à l'aide de requirejs, par exemple:

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

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

Ensuite, lors de l'utilisation du service, je voudrais vérifier si le mock_service a été défini:

//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);
        }

        ...
    });

Donc, ma fonction notionnelle "isDefined" vérifierait juste un module avec le nom (ou les noms?) Donné ayant été défini. Ensuite, dans mon code, s'il est défini, je peux l'exiger et l'utiliser. Sinon, c'est bien aussi.

L'important pour moi est qu'aucune tentative ne soit faite pour charger le module optionnel. Je pourrais essayer/attraper autour de l'instruction require mais cela provoquerait une tentative de chargement à partir du serveur et je ne veux pas cela.

Une autre option serait d'avoir un stub définir que je charge toujours et donc il y a toujours une maquette à exiger que je peux ensuite interroger pour savoir si c'est le vrai ou non mais cela semble aussi du gaspillage.

Existe-t-il quelqu'un qui est profondément intéressé par require.js qui a constaté qu'il avait besoin de cette fonctionnalité et a élaboré une stratégie de mise en œuvre?

Merci d'avance, Rob

35
WooWaaBob

Bien que la réponse de David Wolf soit proche de la cible, elle ne répondait pas pleinement à mes besoins.

Le problème est que require résout de manière asynchrone les exigences, donc dans l'exemple que j'ai donné et en utilisant la suggestion de David require.defined('mock_service') renverra false car bien qu'il ait été spécifié, il n'a pas encore été résolu.

En étudiant cela, j'ai trouvé une autre fonction specified. Dans l'exemple, require.specified('mock_service') renverra true mais la tentative d'obtention d'une référence à l'aide de require('mock_service') échouera car elle n'a pas encore été résolue.

Heureusement, cela est facilement résolu en utilisant la version de rappel de require. Pour mettre tout cela ensemble, nous avons:

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

@David Wolf - merci, ne serait pas arrivé sans votre aide.

46
WooWaaBob

Je cherchais juste cela moi-même, le require global a une méthode "définie" qui prend un nom de module et retourne vrai ou faux.

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

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