10

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.

Adam Terlson
  • 12,610
  • 4
  • 42
  • 63
mrok
  • 2,680
  • 3
  • 27
  • 46
  • 1
    see this question: http://stackoverflow.com/questions/15613577/correct-way-to-implement-jquery-with-require-js – explunit Apr 09 '13 at 13:33

2 Answers2

24

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.

MatthewMartin
  • 32,326
  • 33
  • 105
  • 164
neverfox
  • 6,680
  • 7
  • 31
  • 40
  • 2
    Note, that if you only want to remove jQuery's take over of $, you can do `return $.noConflict();`, which will keep window.jQuery. This way jQuery plugins should all load fine (as shims only, I believe) and you can still have a clean $ (for other libraries to use.) – Dave Lancea Jun 29 '13 at 17:02
  • Edited to reflect that option. – neverfox Jul 13 '13 at 03:34
  • I needed to add `delete window.$` after the `$.noConflict()` call because it was set to `undefined` and mocha would report it as a global leak. – jeremija Nov 25 '13 at 09:51
  • [MAPPING MODULES TO USE NOCONFLICT](http://requirejs.org/docs/jquery.html#noconflictmap) from requirejs site – pryabov Jan 10 '14 at 13:11
  • I followed above step but getting error like Uncaught TypeError: $ is undefined in noconflict.js – vrkansagara Jun 29 '23 at 17:32
0

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;

});
Chris Visser
  • 1,607
  • 12
  • 24
  • I think $ will still be in the global scope with your approach (even if you don't name the parameter $), which is what mrok was trying to avoid – explunit Apr 09 '13 at 14:35
  • It isn't. Tested it to be sure: ''Uncaught ReferenceError: $ is not defined – Chris Visser Apr 09 '13 at 15:03
  • I do not think there is a way to load jquery without adding $ to global scope. My case is that I have already loaded jquery1.4.2 and I would like to use latest version (loaded by require) in no conflict mode. Chris I tried your code and there is $ loaded into global scope - so I have no idea how did you get ' $ is not defined' maybe you have tried to use it before you loaded it? https://github.com/mrok/require – mrok Apr 27 '13 at 22:52
  • You may never get undefined because $ is used by some debuggers, I believe, even if jQuery isn't loaded. You'll see something like `function $() { [Command Line API] }` but that's not jQuery. – neverfox Jun 07 '13 at 03:04