使用 require.js 实现 jQuery 的正确方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15613577/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Correct way to implement jQuery with require.js
提问by riccardolardi
I am using the current stable release of both require.js and jQuery and I am currently including jQuery like this
我正在使用 require.js 和 jQuery 的当前稳定版本,并且我目前正在像这样包含 jQuery
requirejs.config({
paths: {
'jQuery': 'vendor/jquery',
}
});
require(['jQuery'], function(jQuery) {
log(jQuery); // working
});
What I don't get is that I don't really need to explicitly give back jQuery, as this will still work (also in other modules):
我不明白的是我真的不需要明确地返回 jQuery,因为这仍然可以工作(也在其他模块中):
require(['jQuery'], function( // nothing here ) {
log(jQuery); // working
});
Now I'm not sure if this is the correct way of doing it, also because using the $ dollar sign for reference to jQuery doesn't work!
现在我不确定这是否是正确的做法,也是因为使用 $ 美元符号来引用 jQuery 不起作用!
回答by explunit
The key points as I see it:
我认为的关键点:
- jQuery when used with RequireJS registers itself as named module 'jquery' (all lower case). In your example you are trying to use it as 'jQuery', which confuses things a bit since this is also the name of a global function that it registers when loaded (see point #2).
- By default, jQuery registers itself using the global functions "$" and "jQuery", even when used with AMD/RequireJS. If you want to turn off this behavior you have to call noConflict function.
You can wrap your RequireJS reference to jQuery in a noConflict call, as shown in the example below. As far as I can tell, this is the recommended approach when you don't have other modules which need the global $ or jQuery:
requirejs.config({ paths: { 'jquery': 'vendor/jquery', } }); define('jquery-private', ['jquery'], function (jq) { return jq.noConflict( true ); }); require(['jquery-private'], function(jq) { console.log(jq); // working console.log($); // undefined console.log(jQuery); // undefined });
- jQuery 与 RequireJS 一起使用时将自身注册为命名模块“jquery”(全部小写)。在您的示例中,您试图将它用作“jQuery”,这有点令人困惑,因为这也是它在加载时注册的全局函数的名称(参见第 2 点)。
- 默认情况下,jQuery 使用全局函数“$”和“jQuery”注册自己,即使与 AMD/RequireJS 一起使用也是如此。如果要关闭此行为,则必须调用 noConflict 函数。
您可以将 RequireJS 对 jQuery 的引用包装在 noConflict 调用中,如下例所示。据我所知,当您没有其他需要全局 $ 或 jQuery 的模块时,这是推荐的方法:
requirejs.config({ paths: { 'jquery': 'vendor/jquery', } }); define('jquery-private', ['jquery'], function (jq) { return jq.noConflict( true ); }); require(['jquery-private'], function(jq) { console.log(jq); // working console.log($); // undefined console.log(jQuery); // undefined });
See also my answer in this questionregarding how to map other modules to use the private (noConflict) version.
另请参阅我在此问题中关于如何映射其他模块以使用私有(无冲突)版本的回答。
For more background, see these lines from the jQuery source code which are the cause of everything I described above:
有关更多背景信息,请参阅 jQuery 源代码中的这些行,它们是我上述所有内容的原因:
// Expose jQuery to the global object
window.jQuery = window.$ = jQuery;
// Expose jQuery as an AMD module, but only for AMD loaders that
// understand the issues with loading multiple versions of jQuery
// in a page that all might call define(). The loader will indicate
// they have special allowances for multiple jQuery versions by
// specifying define.amd.jQuery = true. Register as a named module,
// since jQuery can be concatenated with other files that may use define,
// but not use a proper concatenation script that understands anonymous
// AMD modules. A named AMD is safest and most robust way to register.
// Lowercase jquery is used because AMD module names are derived from
// file names, and jQuery is normally delivered in a lowercase file name.
// Do this after creating the global so that if an AMD module wants to call
// noConflict to hide this version of jQuery, it will work.
if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
define( "jquery", [], function () { return jQuery; } );
}
UPDATE:the Use with jQuery section of the RequireJS sitehas been updated to reflect the above info. See also this answerfor step-by-step including optimizer. Just want to emphasize again that this noConflict approach only works if allyour plugins are AMD compatible.
更新:RequireJS 站点的Use with jQuery 部分已更新以反映上述信息。另请参阅此答案以了解包括优化器在内的分步说明。只想再次强调,这种 noConflict 方法仅适用于所有插件都与 AMD 兼容的情况。