Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
116 views
in Technique[技术] by (71.8m points)

javascript - Correct way to implement jQuery with require.js

I am using the current stable release of both require.js and jQuery and I am currently including jQuery like this

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):

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!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The key points as I see it:

  1. 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).
  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.
  3. 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
    });
    

See also my answer in this question regarding 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:

    // 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 site has been updated to reflect the above info. See also this answer for step-by-step including optimizer. Just want to emphasize again that this noConflict approach only works if all your plugins are AMD compatible.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...