Correct way to load AMD compatible jQuery plugins into require.js with jQuery in noConflict mode?

Let's say I want to use jquery along with a standard jquery plugin that included non-amd, which was defined using standard closure: (function($))( $.fn.myplugin = { ... } )(jQuery); and all this is inside js/libs/jquery/jquery.myplugin.js .

I am using this configuration:

 require.config({ baseUrl: 'js/', paths: { 'jquery': 'libs/jquery/jquery-noconflict', 'underscore': 'libs/underscore/underscore', 'backbone': 'libs/backbone/backbone', 'jquery-myplugin': 'libs/jquery/jquery.myplugin' }, shim: { 'backbone': { deps: ['underscore', 'jquery'], exports: 'Backbone' }, 'jquery-myplugin': { deps: ['jquery'] } }); 

I load jQuery in conflict free mode in libs/jquery/jquery-noconflict.js because I don't want to pollute the global namespace:

 define(['libs/jquery'], function () { return jQuery.noConflict(true); }); 

and this is how I download the main app.js application:

 define([ 'jquery', 'underscore', 'backbone', 'jquery-myplugin'], function($, _, Backbone, MyPlugin){ //MyPlugin is always undefined, not even sure if //I should be passing it here if it only extends jQuery? }); 

Now here is the problem I am experiencing - although I can use all the libraries defined above without any problems, I could not develop the correct shim configuration to load jquery plugins that do not support AMD.

I tried to configure jquery-myplugin as deps jquery (and vice versa), but I could never get it to work.

It seems that I have a problem with the following scenario:

  • jQuery loads in non-conflict mode.
  • plugin code is run extending the jQuery instance above
  • I can use $ in my application, extended by the plugin code, so $ .myplugin is available.

I have seen similar questions floating around, but none of them actually solve this problem, giving only vague suggestions like "use shim config" ...

Edit

I also tried using

 "jquery-myplugin": { deps: ["jquery"], exports: "jQuery.fn.myplugin" } 

And although plugin methods are available after loading as an AMD module in this way, I still cannot access: $('.class').myplugin() by default, the $ object was not extended by myplugin code.

+6
source share
3 answers

Using jQuery.noConflict(true) removes the jQuery global variable. When your plugin loads, it tries to access jQuery , but cannot, causing this crash.

If your plugin was a module, it could access jQuery as a dependency. Or you can leave jQuery available as global.

+3
source

First make sure that the "/ to / jquery-myplugin path" actually extends window.jQuery , not $

noConflict () leaves the window.jQuery object defined, but detaches itself from window.$ In some new browsers, window.$ is built into an alias for the built-in document.querySelectorAll function.

Secondly, your myplugin should NOT be returned, as it cannot be used on its own. Since it extends jQuery, return jQuery from a call to myplugin.

Finally, the / to / jquery -myplugin path is not a module . This is a simple JS file. Perhaps RequireJS is trying to load it as a module and cannot find the define() call, which leads to a mess. Try actually adding the extension “.js” to the link to the RequireJS signal that it needs to use “js!”. plugin to download the resource.

 require.config({ paths: { "jquery": "path/to/jquery", "jquery-myplugin": "path/to/jquery-myplugin.js" }, shim: { "jquery": { init: function() { return window.jQuery.noConflict(); }, "jquery-myplugin": { deps: ['jquery'] init: function($) { return $; }, } } }); 
-1
source

I had the same problem as you today. Here is how I could fix it:

 requirejs.config({ "baseUrl": "js/lib", "paths": { "app": "../app" } }); // Final version of jQuery with all needed plugins. define("jquery", ["jquery-core", "myplugin"], function(jqCore) { return jqCore; }); // Define core jQuery module. define("jquery-core", ["jquery-1.9.1.min"], function() { return jQuery.noConflict(true); }); // This module exposes jquery module to the global scope and returns previous defined version. define("jq-global", ["jquery-core"], function(jqCore) { var tmp = jQuery; jQuery = jqCore; return tmp; }); // Define your plugin here, and don't forget to reset previous jQuery version. define("myplugin", ["jq-global", "jquery.myplugin"], function(jqGlobal, jqPlugin) { jQuery = jqGlobal; }); // Load the main app module to start the app requirejs(["app/main"]); 

Now in my app / main.js file I can do the following:

 define(["jquery"], function($) { $('body').myplugin(); }); 

The idea here is to expose jQuery during the execution of the plugin code. So far I have not tested the solution in a larger environment with a large number of modules for loading, so I can not guarantee that it will work in the long run;)

Edit

This solution will not work !! Since requirejs does not load scripts sequentially, it is possible that the js file of the plugin file is loaded before jquery, which will lead to a failure of execution. Sorry for that.

If anyone has another idea ...

-1
source

All Articles