在require js中,是否可以判断脚本是否作为data-main
加载?例如,我有一个可以用作data-main
或模块的脚本:
// script.js
if (this_is_data_main()) {
console.log('do something main');
} else {
console.log('do something else');
}
我可以通过将信息写为全局变量来考虑黑客攻击,例如:
//index.html
<!doctype html>
...
<script> window.app.main = 'script'; </script>
<script data-main="script.js" src="require.js"></script>
更新了script.js:
// script.js
if (window.app && window.app.main === 'script') {
console.log('do something main');
} else {
console.log('do something else');
}
答案 0 :(得分:1)
RequireJS不提供&#34;官方&#34;做你想做的事。这是一种非官方的方式,很脆弱。但是,我认为您不应该依赖于检测脚本是否通过data-main
加载。
RequireJS没有直接的方法去做你想做的事情。如果您阅读RequireJS的代码,您会看到它显示data-main
并最终将其附加到当前配置的deps
选项。除了一些路径计算之外,没有其他处理。 (路径计算详细信息对于您在此处提出的较大问题并不重要,因此我会跳过这些详细信息。)当RequireJS完成data-main
时,您问题中的代码大致相同相当于:
<script src="require.js"></script>
<script>
require.config({
deps: ["script"]
});
</script>
您可以检查deps
并查看您的模块是否在那里。您在此位置deps
找到require.s.contexts._.config.deps
。顺便说一句,下划线是默认上下文的名称。但正如您可以通过这个奇怪的位置告诉我这是使用私有API,可能会随着RequireJS的未来版本而改变。这是一个问题。另一个问题是,如果require.config
再次被deps
值调用,则deps
的第一个值将被覆盖。所以这将取决于具体情况而失败。我的味道太脆了。
最终,我不会依赖于模块行为取决于模块是否通过data-main
列出而不是其他方式加载。我上面显示的是使用data-main
的等效内容。这是另一个:
<script src="require.js"></script>
<script>
require(["script"]);
</script>
我可以列出一堆其他变体。 关键是从模块加载的角度来看data-main
是一种便利。它不应该被赋予更多的意义而不是方便。我已经在各种情况下使用data-main
和上面显示的两个替代方案。上下文通常会确定哪些选项是可行的或可取的。例如,我已经在SO上回答了问题,其中OP在其自己的代码运行时已经加载了RequireJS的上下文中运行。所以他们就不会甚至能够依赖data-main
。 (例如,对于在较大框架中充当插件的组件,可能会发生这种情况:框架使用RequireJS,因此它使RequireJS可用于插件,但插件仅限于添加script
元素。)
依赖data-main
的另一个问题是这是一个RequireJS的事情。可以使用其他工具(如Webpack)加载AMD模块,也可以使用其他工具(如Webpack)加载AMD模块。 如果您的代码取决于data-main
,则在使用其他工具时,它无法正常工作。
您可以让主模块导出一个初始化函数,该函数根据用户需要选择并配置模块。
如果您希望在加载模块后立即启动并且不必调用任何函数,那么在不污染全局JavaScript空间的情况下执行此操作的一种方法是让您的模块查找着名的script
具有类型id
的元素(特定class
或特定application/json
)。由于它是JSON,因此浏览器不会执行它,但是需要它的脚本可以访问它。它将包含模块读取配置的JSON对象。 This question处理如何从脚本中获取JSON。