javascript - RequireJS:在指定配置中存在路径别名的绝对路径名时不触发 require 回调

标签 javascript requirejs

这里 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 影响模块的加载,则名称将是出现在 requiredefine 调用中的字符串。将该模块列为依赖项。因此,在问题中使用您的配置,如果您执行 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 传递给 requiredefine,然后检查 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/

相关文章:

javascript - Spring MVC 使用 javascript 下载 xls

javascript - 如何使用 ajax/javascript 在表单中附加文本?

javascript - 如何截取托管在 Amazon S3 上的视频的屏幕截图?

javascript - 将 mouseenter 与 if 语句结合起来?

javascript - 如何使用 RequireJS AMD 让函数公开其对象和成员方法

ruby-on-rails - 有没有替代 Django 的 Rails Assets 管道?

javascript - JS Facebook API 请求似乎中断了 session

javascript - 创建一个 JS 库并声明其他库所依赖的内容

javascript - 了解何时以及如何使用 Require.JS

javascript - 使用 Jasmine 检查 Backbone/requireJs 项目