在RequireJS中 - 不能在路径中别名jQuery名称

时间:2012-01-04 23:37:45

标签: javascript jquery requirejs

我是RequireJS菜鸟。当我使用“require.config”并包含一个名称与jQuery不同的jQuery路径时,结果不符合预期。

这是一个非常简单的例子来帮助解释我的问题。

文件结构

root
├── Index.htm
└── scripts
    ├── libs
    │   ├── jquery-1.7.1.js
    │   └── require.js
    ├── main.js
    └── someModule.js

的index.htm

<html>
<head>
    <title>BackboneJS Modular app with RequireJS</title>
    <script data-main="scripts/main" src="scripts/libs/require.js"></script>
</head>
<body>
    <h3>BackboneJS is awesome</h3>
</body>
</html>

这里脚本标记引用了scripts / libs中的require。当require运行时,应该执行脚本目录中名为main.js的JavaScript文件。

main.js

require.config({
   "paths": {
           "mod1": "someModule"
   }
});
require(["mod1"], function (sm) {
    console.log(sm.someValue);
});

根据我的经验,“mod1”可以是任何内容,只要它在require.config路径和require方法中引用相同即可。

someModule.js

define([], function () {
    console.log();
    return { someValue: "abcd" };
});

为了完整起见,我收录了someModule.js

当我包含JQuery时,会出现感觉到的不稳定。

在下面的main.js中,我将jQuery添加到config和require方法中。

Main.js

require.config({
    "paths": {
        "jquery": "libs/jquery-1.7.1"
        ,"mod1": "someModule"
    }
});

require(["mod1", "jquery"], function (sm, $) {
    console.log(sm.someValue);
    console.log($);
});

随着jQuery的增加,一切似乎仍然有效。 “console.log($)”编写了jQuery函数。

现在是踢球者。在下面的代码中,我在两个路径中将“jquery”更改为“jqueryA”并且需要

require.config({
    "paths": {
        "jqueryA": "libs/jquery-1.7.1"
        ,"mod1": "someModule"
    }
});

require(["mod1", "jqueryA"], function (sm, $) {
    console.log(sm.someValue);
    console.log($);
});

现在“console.log($)”写入null。

这应该是预期的吗?这个名称必须是jquery的原因是什么,但对于mod1,它可以是什么?

我可以毫无问题地解决这个问题,但这个问题似乎很奇怪。我知道我可以使用组合的RequireJS和jQuery文件,但是当jQuery有更新时,我不想依赖于RequireJS来包含新的jQuery。

3 个答案:

答案 0 :(得分:9)

在jQuery 1.7中,他们决定支持AMD加载。为此,它定义了一个名为“jquery”的模块,该模块将对jQuery对象的引用传回。当你用另一个名字(例如'jqueryA')定义你的jquery路径时,事情并没有像你想象的那样完全破解。

jquery脚本始终将自己定义为名为“jquery”的模块,该模块已在app中注册了require。当您命名路径快捷方式'jquery'并且'jquery'作为依赖项加载时,require实际上引用了由jquery-1.7.1.js定义的'jquery'模块,该模块确实传回了正确的引用。当您命名模块快捷方式jqueryA时,您现在引用了未定义的引用,因为除了通过名为“jquery”的模块之外,jquery脚本本身不会传回引用。我知道,这太傻了。

jquery脚本将模块定义为“jquery”,并期望您只需将其引用为“jquery”。如果你想将它作为另一个名称引用(并作为奖励,防止它与其他加载的jquery库发生冲突),请使用以下方法:

Use requirejs and jquery, without clobbering global jquery?

答案 1 :(得分:4)

这是我的解决方法,基于我读过的Require.JS 2.1.0的实现:

define.amd.jQuery = false;

require.config({
    ...

    shim: {
        "jQuery-1.8.2": {
            exports: "jQuery"
        }
    }

    ...
});

答案 2 :(得分:2)

我相信我找到了问题的答案。

可选择调用AMD define()来注册模块 https://github.com/documentcloud/underscore/pull/338#issuecomment-3253751

以下是上一个链接的引用。即使它属于下划线,我相信它也与JQuery有关。

  

所有AMD加载器都允许将模块ID映射到部分ID   路径,通常配置被称为'路径',所以你要做什么   想:

     

requirejs.config({       路径:           下划线:'js / libs / underscore-1.2.3.min'       }}; require(['underscore'],function(){});由于下划线被其他更高级别的模块(如主干)使用,因此是一种常见的依赖关系   name需要用于表达对公共依赖的通信   下划线,将依赖性称为“下划线”是有意义的。   路径配置提供了一种方法来映射到您的特定URL   想要用于那种依赖。

这是一个非常好的描述AMD和命名模块问题的咆哮。

具有命名定义的AMD模块。获得了多少痛苦? http://dvdotsenko.blogspot.com/2011/12/amd-modules-with-named-defines-so-much.html

从上面的链接引用

  

如果正确使用模块的唯一方法是强行使用   终端开发人员在配置文件中将其名称​​再次硬编码   消费点,(仅在这方面)为什么浪费时间,精力和   首先在模块中对名称进行硬编码(更不用说原因了)   对那些需要在不同模块下加载模块的开发人员感到悲伤   姓名/来自其他来源)?

在这篇文章中,James Burk建议不要使用名称模块。 https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon

  

通常你不应该注册一个命名模块,而是注册   作为一个匿名模块:

     

这允许您的代码用户重命名   您的库的名称适合他们的项目布局。它也是   允许他们将您的模块映射到使用的依赖项名称   其他图书馆。例如,可以映射Zepto.js以实现   'jquery'模块ID的模块任务。

     

有一些值得注意的例外会注册为命名模块:

     

•jQuery•下划线

异常糟透了。例外情况使得新手很难。