这里 require.js 配置中有一个路径别名“jquery”
Require.JS 正在触发“jquery”的 require 回调,但如果为 jquery 模块指定了绝对路径,则不会触发 require 回调。
<script type="text/javascript">
var require = {
baseUrl : "../../",
paths : {
'jquery' : '/js/jquery-1.8.3',
},
};
</script>
<script type='text/javascript' src='/js/require.js'></script>
<script type="text/javascript">
require(['jquery'],function(obj) {
console.info("jquery loaded","alias");
});
require(['jquery'],function(obj) {
console.info("jquery loaded","alias");
});
require(['/js/jquery-1.8.3.js'],function(obj) {
console.info("jquery loaded","absolute path");
});
</script>
我期望执行最后一个 require 语句中的 console.info,但它没有触发。看起来如果您需要路径别名然后需要绝对路径,则不会触发回调。
这是 Require.JS 中的错误还是使用路径别名和绝对路径触发回调的任何替代方法?
最佳答案
正确。尝试以两个不同的名称加载相同模块是行不通的。有充分的证据表明这是设计使然。
RequireJS 将模块视为单例。 (“singelton-ness”的范围是 RequireJS 上下文。因此,同一个模块可以为一个上下文实例化一次,并为不同的上下文实例化第二次,但它永远不会为另一个上下文实例化两次相同的上下文。)当 RequireJS 加载模块时,该模块会获取一个名称。如果 define
调用将字符串作为第一个参数,则名称就是该字符串。否则,如果没有 map
影响模块的加载,则名称将是出现在 require
或 define
调用中的字符串。将该模块列为依赖项。因此,在问题中使用您的配置,如果您执行 require(['jquery'], ...
或有一个模块 foo
定义为 define (['jquery'], ...
那么将为 js/jquery-1.8.3
中找到的模块指定的名称为 jquery
。事实上,在模块内部,您可以通过执行以下操作来获取模块名称:
define(['module'], function (module) {
console.log("my module name: " + module.id);
});
好的,那么如果您的模块需要使用两个不同的模块名称两次,会发生什么情况?请记住,模块是单例的,因此 RequireJS 不会执行 define
两次。模块应该获取哪个id
?
在实践中,几乎总是的情况是,当相同的模块代码以两个不同的名称加载时,这是一个编程错误,而不是开发人员的错误真的很想做。我从来没有遇到过使用 RequireJS 的代码库,其中将 jQuery 加载为 jquery
并使用带有版本号的路径是有效的。后一种情况确实是一个错误。因此,当您尝试使用两个不同名称加载同一模块时,RequireJS 会立即中断,而不是使用某种可能会导致意外的默认行为。这是安全的做法。
现在,如果您确实必须能够加载具有两个名称的同一模块,那么您可以做到这一点,但您必须明确说明您想要什么:您可以使用map
。这将在您要使用的模块名称之间建立明确的关系。映射的作用基本上是说“当模块 X 中的代码需要模块 Y 加载模块 Z 时”。所以在你的情况下:
map: {
'*':
'/js/jquery-1.8.3': 'jquery'
}
}
这表示“当任何模块中的代码 (*
) 需要 /js/jquery-1.8.3
时,改为加载 jquery
”。如果您想知道,这不会导致循环依赖。 RequireJS 将看到 /js/jquery-1.8.3
传递给 require
或 define
,然后检查 map
并将其转换为jquery
,然后会在paths
中找到jquery
并将其转换为/js/jquery-1.8.3
然后添加 .js
扩展名并获取模块。经过 paths
后,它不会返回 map
,因为它从 paths
获得的结果是路径,而不是模块名称(并且 map
仅转换模块名称)。
请注意,在上面的 map 中,仅加载了一个名为 jquery
的模块。如果在其中使用 module.id
,则它将始终具有值 "jquery"
并且不能具有任何其他值。
重要提示:您不应将 .js
放入 require
调用中,否则它将无法工作:require(['/js/jquery-1.8.3'],...
。
关于javascript - RequireJS:在指定配置中存在路径别名的绝对路径名时不触发 require 回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33594911/