RequireJS:在指定config中存在路径别名的绝对路径名时,不触发要求回调

时间:2015-11-08 14:14:53

标签: javascript requirejs

这里有路径别名" jquery"在require.js config

Require.JS触发" jquery"但如果为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中的错误还是通过路径别名和绝对路径触发回调的任何其他方法?

1 个答案:

答案 0 :(得分:1)

正确。尝试以两个不同的名称加载相同的模块不起作用。有很好的证据证明这是设计的。

RequireJS将模块视为单例。 (“singelton-ness”的范围是一个RequireJS上下文。因此,相同的模块可以为一个上下文实例化一次,第二次实例化为不同的上下文但它永远不会被实例化两次相同的上下文。)当RequireJS加载模块时,模块获取一个名称。如果define调用将字符串作为第一个参数,则名称为此字符串。否则,如果没有map影响模块的加载,则名称将是requiredefine中出现的字符串,该模块将模块列为依赖项。因此,在问题中使用您的配置,如果您执行require(['jquery'], ...或具有定义为foo的模块define(['jquery'], ...,那么将在{{1}处找到将给予模块的名称是js/jquery-1.8.3。然后有一个事实是,在模块内部,您可以通过执行以下操作来获取模块名称:

jquery

好的,如果您的模块需要两次使用两个不同的模块名称会发生​​什么?请记住,模块是单例,因此RequireJS不会执行define(['module'], function (module) { console.log("my module name: " + module.id); }); 两次。模块应该得到哪个define

在实践中,几乎总是的情况是,当相同的模块代码以两个不同的名称加载时,这是一个编程错误而不是开发人员的东西真的很想做。我从来没有碰到使用RequireJS的代码库,在这个代码库中,将jQuery加载为id并使用带有版本号的路径是有效的。后一种情况确实是一个错误。因此,当您尝试以两个不同的名称加载相同的模块时,RequireJS会立即中断,而不是使用某种可能导致意外情况的默认行为。这是安全的事情。

现在,如果你真的必须能够使用两个名称加载相同的模块,那么你可以这样做但你必须明确你想要的东西:你可以使用jquery。这将在您要使用的模块名称之间建立明确的关系。地图的作用基本上是“当模块X中的代码需要模块Y加载模块Z时”。所以在你的情况下:

map

这表示“当任何模块中的代码(map: { '*': '/js/jquery-1.8.3': 'jquery' } } )需要*加载/js/jquery-1.8.3时”。如果你想知道,这不会导致循环依赖。 RequireJS会将jquery传递给/js/jquery-1.8.3require,然后检查define并将其转换为map,然后会在jquery中找到jquery paths并将其转换为/js/jquery-1.8.3,然后添加.js扩展名并获取模块。完成paths之后,它不会返回map,因为它从paths获得的结果是路径,而不是模块名称(并且map仅转换模块名称)。

请注意,使用上面的地图,只加载了一个模块,名为jquery。如果在其中使用module.id,则其总是具有值"jquery",并且不能具有任何其他值。

重要提示:您不应将.js置于require来电,否则无效:require(['/js/jquery-1.8.3'], ...