2013-02-13 116 views
27

我希望能够有选择地定义一个模块,然后在我的代码中使用它。我正在考虑的特定情况是在调试/测试环境中加载模拟/存根模块,但不是在我上线时加载。下面是例如:使用requirejs是否可以检查一个模块是否被定义而不尝试加载它?

在JS文件将被任选加载(伪码)的HTML文件:

//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已被定义

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

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

然后使用该服务时,我想检查:

//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,他们发现他们需要这个功能并制定了实施策略?

谢谢你在前进,罗布

回答

41

尽管大卫·沃尔夫的答案已接近标准,但并未完全满足我的需求。

问题是需要异步解决要求,所以在我给出的示例中,使用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); 
    }); 
} 

@大卫狼 - 谢谢,不会没有你的帮助到那里。

56

我只是在寻找这个自己的需要全球上有一个“定义”的方法,这需要模块名称和返回true或false。

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

// returns false 
require.defined("not/yet/loaded"); 
+0

Thx - 这几乎满足了我的需求,帮助我找到了正确答案,现在我已添加并标记为完整解决方案。 – WooWaaBob 2013-02-22 16:43:37

+0

+1很好的答案和一个不错的功能,不知道这一个! – thomaux 2013-06-11 13:29:42

+0

只是好奇,如果在杏仁版本的任何替代? – 2016-04-07 03:48:47

相关问题