4

I want to get rid of the global jQuery objects (window.$ and maybe also window.jQuery).

data-main:

require.config({
    paths: {
        "jquery": "jquery-2.0.0"
    },
    shim: {
        "bootstrap": {
            deps: ["jquery"]
        },
        "jquery": {
            deps: [],
            init: function() {
                return this.jQuery.noConflict(true);
            },
            exports: "jQuery"
        }
    }
});

require(["jquery", "bootstrap"], function($) {
    // ...
});

What's wrong with this code? "init" is never called.

explunit
  • 18,967
  • 6
  • 69
  • 94
bert
  • 466
  • 3
  • 7

2 Answers2

4

It is not called most likely because jQuery implements AMD module and there is no need for shim.

Tomas Kirda
  • 8,347
  • 3
  • 31
  • 23
  • 1
    But I would say it's wrong to create global objects when you're loaded as an AMD module... (otherwise it's easier to use jQuery inside the Chrome console) – bert May 24 '13 at 22:37
  • @bert agree re global objects, but jQuery predates RequireJS and they have large number of plugins they didn't want to break when adding AMD. See my answer below and also [this answer](http://stackoverflow.com/questions/15613577/correct-way-to-implement-jquery-with-require-js/15649611#15649611) for other background. – explunit Jun 28 '13 at 13:27
  • Also note that you should not remove these globals unless all dependencies are also AMD. For example, if you are using non-AMD plugins like jquery-ui you can't eliminate these globals. – Shital Shah Nov 03 '13 at 16:01
4

The recently-updated Use with jQuery page on the RequireJS site explains more about why this happens and what you can do to resolve it. Here is the relevant part:

jQuery registers itself as the global variables "$" and "jQuery", even when it detects AMD/RequireJS. The AMD approach advises against the use of global functions, but the decision to turn off these jQuery globals hinges on whether you have non-AMD code that depends on them. jQuery has a noConflict function that supports releasing control of the global variables and this can be automated in your require.config, as we will see later.

And if you want to suppress these global functions, you need to use a map config to a noConflict wrapper module rather than a shim config. As @tomaskirda pointed out, jQuery doesn't fire shim.init for libraries that support AMD. The relevant code from the Use with jQuery page:

require.config({
    // Add this map config in addition to any baseUrl or
    // paths config you may already have in the project.
    map: {
      // '*' means all modules will get 'jquery-private'
      // for their 'jquery' dependency.
      '*': { 'jquery': 'jquery-private' },

      // 'jquery-private' wants the real jQuery module
      // though. If this line was not here, there would
      // be an unresolvable cyclic dependency.
      'jquery-private': { 'jquery': 'jquery' }
    }
});

// and the 'jquery-private' module, in the
// jquery-private.js file:
define(['jquery'], function (jq) {
    return jq.noConflict( true );
});
explunit
  • 18,967
  • 6
  • 69
  • 94
  • Problem with this is it appears to break the `shim` dependencies. I am trying to use `jquery-ui` and using a shim config to set `jquery` as a dependency, however, it doesn't appear to be loading correctly. If I remove the `map` config it works fine. – James Mar 05 '14 at 08:59
  • Thanks james.. doc says `the shim example will not work since shimmed libraries need a global jQuery` – eugene Feb 27 '15 at 01:43