С requirejs можно проверить, не определен ли модуль, не пытаясь его загрузить?
Я хочу иметь возможность опционально определять модуль, а затем использовать его или нет в моем коде. Особая ситуация, которую я рассматриваю, заключается в загрузке модулей mock/stub в среду отладки/тестирования, но не тогда, когда я перехожу вживую. Вот пример:
В 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, который обнаружил, что им нужна эта функциональность, и разработал стратегию для реализации?
Спасибо заранее, Роб
Ответы
Ответ 1
Хотя ответ Дэвида Вольфа был близок к знаку, он не полностью соответствовал моим потребностям.
Проблема заключается в том, что требуется асинхронное решение требований, поэтому в примере, который я дал, и использование предложения David require.defined('mock_service')
вернет false
, потому что, хотя он был указан, он еще не разрешен.
При исследовании этого вопроса я нашел еще одну функцию specified
. В примере require.specified('mock_service')
будет возвращен true
, но затем попытка получить ссылку с помощью require('mock_service')
завершится с ошибкой, поскольку она еще не разрешена.
Это, к счастью, легко фиксируется с использованием требуемой версии обратного вызова. Соединяя все это, мы имеем:
if (require.specified('mock_service')) {
require( [ 'mock_service' ], function (mock) {
mock.init(real_service);
});
}
@Давид Волк - спасибо, не получил бы там без вашей помощи.
Ответ 2
Я просто искал это сам, для этого требуется, чтобы global имел "определенный" метод, который принимает имя модуля и возвращает true или false.
// returns true
require.defined("my/awesome/defined/module");
// returns false
require.defined("not/yet/loaded");