How use require.js to load jQuery with noConflict

2020-08-15 04:43发布

问题:

I am trying to load jquery in noConflict mode by using require

require.config({
    paths: {
        'jquery': 'libs/jquery-req',
        underscore: 'libs/underscore',
        backbone: 'libs/backbone'
    },
    shim: {
        jquery: {
            init: function() {
                console.log('jq init');
                var jq = this.jQuery.noConflict(true);
                jq.support.cors = true;

                return jq;
            },
            exports: '$'
        },
        backbone: {
            deps: ['underscore', 'jquery'],
            init: function() {
                console.log('b init');
            },
            exports: 'Backbone'
        },
        underscore: {
            exports: '_'
        }
    }
});

and use it like that:

define([
    'jquery',
    'underscore',
    'backbone'
], function(jq, _, Backbone) {
    console.log(jq);
    var initialize = function() {
//        Router.initialize();
    };

    return {
        initialize: initialize
    };
});

unfortunately it seems shim.jquery.init function is never called. Can someone try to help me understand why? What is strange when I rename jquery -> jquery-reg then it seems to work, but it requires to change dependency defined in every files.

回答1:

Create the following noconflict.js module:

define(["jquery"], function($) {
  //drop the `true` if you want jQuery (but not $) to remain global
  return $.noConflict(true); 
});

Then, in your require.config add:

map: {
  "*": {
    "jquery": "noconflict"
  },
  "noconflict": {
    "jquery": "jquery"
  }
}

The noconflict version of jQuery will be handed to all modules (except noconflict). Get rid of the jQuery shim.

Please note that going the path of keeping jQuery out of the global namespace will prevent you from using any jQuery plugins that are non-AMD without modifying those plugins to be AMD modules. Shim doesn't do anything magical to take advantage of this setup. The same goes for any non-AMD module you might want to shim that depends on something you've made "pure" AMD.



回答2:

I'm using this one:

require.config({
    paths: {
        jquery: 'libraries/jquery/jquery.min',
        underscore: 'libraries/underscore.min',
        backbone: 'libraries/backbone.min',
        jquery_ui: 'libraries/jquery/jquery.ui.min',
    },

    shim: {
        'backbone': {
            deps: ['underscore', 'jquery'],
            exports: 'Backbone'
        },
        'underscore': {
            exports: '_'
        },
        'jquery_ui': {
            deps: ['underscore', 'jquery'],
            exports: 'ui'
        }
    }
});

Then in my app i use local scopes to define jquery's instance. In the below case $ is jquery, but it can be something else as well.

define([
    'jquery', 
    'backbone'
    ], function ($, Backbone) {

    'use strict';

    var app = Backbone.View.extend({
        el: 'body',

        initialize: function() { },

    });

    return app;

});