使用require.js实现jQuery的正确方法

ric*_*rdi 29 javascript jquery amd requirejs

我正在使用require.js和jQuery的当前稳定版本,我目前包括这样的jQuery

requirejs.config({
paths: {
    'jQuery': 'vendor/jquery',
}
});

require(['jQuery'], function(jQuery) {
    log(jQuery); // working
});
Run Code Online (Sandbox Code Playgroud)

我没有得到的是我真的不需要明确地回馈jQuery,因为它仍然可以工作(也在其他模块中):

require(['jQuery'], function( // nothing here ) {
    log(jQuery); // working
});
Run Code Online (Sandbox Code Playgroud)

现在我不确定这是否是正确的方法,也因为使用$ dollar符号来引用jQuery不起作用!

exp*_*nit 39

我看到的关键点:

  1. 与RequireJS一起使用时,jQuery将自身注册为命名模块'jquery'(全部小写).在您的示例中,您尝试将其用作"jQuery",这会使事情有点混乱,因为这也是加载时注册的全局函数的名称(请参阅第2点).
  2. 默认情况下,jQuery使用全局函数"$"和"jQuery"注册自己,即使与AMD/RequireJS一起使用也是如此.如果要关闭此行为,则必须调用noConflict函数.
  3. 您可以在noConflict调用中将RequireJS引用包装到jQuery,如下面的示例所示.据我所知,当你没有其他需要全局$或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
    });
    
    Run Code Online (Sandbox Code Playgroud)

另请参阅此问题中有关如何映射其他模块以使用私有(noConflict)版本的答案.

有关更多背景信息,请参阅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; } );
    }
Run Code Online (Sandbox Code Playgroud)

更新:RequireJS网站的" 使用jQuery"部分已更新,以反映上述信息.有关包括优化程序在内的分步操作,请参阅此答案.只是想再次强调一下,这种noConflict方法只有在所有插件都兼容AMD的情况下才有效.