I don't know if this is possible, but I'm trying to develop an app that doesn't create a global $
or jQuery
variable when loading in jQuery, but still works with some plugins that weren't developed with AMD in mind.
main script
require.config({
baseUrl: '/js/lib',
paths: {
jquery: 'vendor/jquery-2.1.3.min',
somePlugin: 'vendor/somePlugin.min'
},
map: {
'*': { jquery: 'secret-jquery' },
'secret-jquery': { jquery: 'jquery' }
},
shim: {
somePlugin: ['jquery']
}
});
secret-jquery.js
define(['jquery'], function (jQuery) {
return jQuery.noConflict(true);
});
Unfortunately, it sets up the jQuery plugin like so:
somePlugin.min.js
$.fn.somePlugin = function (options) {
// ...
});
I don't need the shim if I change the plugin source to use define
, i.e.
define(['jquery'], function ($) {
$.fn.somePlugin = function (options) {
// ...
});
});
But that breaks the rule of not modifying third-party plugins, especially popular plugins that I might later swap out with an updated version.
I cannot use a global $
or jQuery
variable because my script needs to inject jQuery onto a page that may already have loaded it (and consequently loaded a different version with an incompatible API, and my jQuery can't break anything on the page).
Is there a clean way to do this, or is the best way to just change the plugin code? I can't think of any other way to do it, save loading in the script via an XMLHttpRequest, wrapping it with a define
call, and eval
ing it, which seems like it'd defeat the purpose of letting RequireJS take care of the dirty work.
How we're doing this is that we're defining our secret-jquery.js like so:
define(['jquery', 'vendor/somePlugin.min'], function (jQuery) {
return jQuery.noConflict(true);
});
With our config looking like:
require.config({
baseUrl: '/js/lib',
paths: {
jquery: 'vendor/jquery-2.1.3.min',
somePlugin: 'vendor/somePlugin.min'
},
map: {
'*': { jquery: 'secret-jquery' },
'secret-jquery': { jquery: 'vendor/jquery-2.1.3.min' }
},
shim: {
somePlugin: ['jquery']
}
});
This has given us the least amount of problems with jQuery plugins that do not use RequireJS while still allowing us to take advantage of RequireJS in our own code. Sure, we aren't keeping track of which jQuery plugins a piece of code uses, but in my opinion, jQuery plugins are not usually developed to make this easy anyway since, even when they are able to use RequireJS, they don't normally return anything and instead extend jQuery itself.