我希望能够选择性地定义模块,然后在我的代码中使用它。我正在考虑的特殊情况是在调试/测试环境中加载模拟/存根模块,但不是在我上线时。这是一个例子:
在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,他们发现他们需要这个功能并制定了实施策略?
提前谢谢你,Rob
答案 0 :(得分:62)
我自己只是在寻找这个,require global在其上有一个“已定义”的方法,它接受一个模块名称并返回true或false。
// returns true
require.defined("my/awesome/defined/module");
// returns false
require.defined("not/yet/loaded");
答案 1 :(得分:45)
虽然大卫·沃尔夫的回答接近于标记,但并不完全符合我的需要。
问题是需要异步解析需求,因此在我给出的示例中使用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);
});
}