2

I have written a jQuery plugin using require, wrapped it in almond, and loaded it through a shim config in another app. Unfortunately, require is exposing the global jQuery to the plugin rather than the local one. My code:

plugin.js

(function() {
    // almond code
    // other dependencies
    require(dependencies, function (dependencies) {
        !function($) {
            // window.jQuery == $ -> true
            $.fn.plugin = function(options) { return this; }
        }(jQuery);
    });
})();

main.js

require.config({
    paths: { 'jquery': 'vendor/jquery-1.9.1.min' },
    shim: { 'plugin': ['jquery'] }
});

require(['jquery','plugin'], function ($) {
    // window.jQuery == $ -> false
    $('#plugin').plugin(options);
    // error, object [Object object] has no method "plugin"
);

Shouldn't shim load the plugin code exposing the local jQuery module to the plugin's global scope?

Matthew James Davis
  • 12,134
  • 7
  • 61
  • 90
  • how could `$` **not** be global jQuery in plugin.js, given that `$` is not a parameter in your require callback? – explunit Jul 10 '13 at 20:09
  • I don't follow your question. The requirejs documentation says that you should use shim with plugins that expect to use a variable from the global scope, such as a jquery plugin. That's what I'm doing here: I'm attempting to use the global jQuery object like any plugin would in the plugin code and then shimming it. – Matthew James Davis Jul 10 '13 at 20:42
  • I probably misunderstood too. I thought you were expecting `window.jQuery == $` to be FALSE in plugin.js and could not see why you expected that. What if you make main.js have `require(['jquery','plugin'], function () {` (take away the $ as a parameter)? – explunit Jul 10 '13 at 21:33
  • I do expect it to be false. I want it to be false. I expect require to do something along the lines of load up the code in plugin with the local jQuery exposed to the plugin's global scope, run the code, and then remove the global exposure. Your solution is what I have at the moment, but it doesn't work the same way the other jQuery plugins I've used have. I want it to work with a standard shim in a jquery dependent require app. – Matthew James Davis Jul 11 '13 at 01:05

1 Answers1

3

I believe the problem is that you are trying to use shim with AMD modules, when really that feature is designed for non-AMD modules. From that section of the documentation:

Remember: only use shim config for non-AMD scripts,scripts that do not already call define(). The shim config will not work correctly if used on AMD scripts, in particular, the exports and init config will not be triggered, and the deps config will be confusing for those cases.

If you want to keep jQuery out of global scope and still use it with your other modules, you can follow the Mapping Modules to use noConflict approach:

If all of your modules (including any third party jQuery plugins or library code that depend on jQuery) are AMD compatible and you want to avoid having $ or jQuery in the global namespace when they call require(['jquery']), you can use the map config to map the use of jQuery to a module that calls noConflict and returns that value of jQuery for the 'jquery' module ID.

See also Using private jquery with RequireJS - issue after optimisation for a step-by-step example.

Community
  • 1
  • 1
explunit
  • 18,967
  • 6
  • 69
  • 94