0
votes

I'm working on a large site that has a lot of legacy code. Inline scripts, old libraries, etc etc. It's stuff that I can't blanket remove because it's being used on many pages, but we are moving in a new direction. Requirejs, marionette and backbone. I can't just take ALL of our thousands of lines of code refactor them. Not immediately anyways. So, in the mean time, we'll have a two headed monster. Legacy code the way it is, new code in the backbone, marionette, requirejs app.

My issue is with loading jquery in my current, very basic, requirejs based setup. I've got jquery v1.9.1 shimmed in to load before require, but it appears to be conflicting somehow with the different version of jquery(1.7.2) loaded from the head. Sitewide, all of the functions (such as the twitter bootstrap jquery based plugins, etc) that attach to the old version of jquery appear to get wiped out by the version of jquery I'm loading in with require. My guess is the shim, which loads jquery BEFORE any require based code, as far as I understand anyways, is killing my old jquery object.

How do I avoid this? How do I keep my new version of jquery contained to the require.js object and not have it interfere with the old legacy code?

Thank you very much. Code details can be provided if asked for, but I hope the concept of what I'm trying to do here is clear enough.

2

2 Answers

0
votes

Have you tried the jQuery.noConflict for example ...

<script src='jquery-1.3.2.js'></script>
<script>
var jq132 = jQuery.noConflict();
</script>
<script src='jquery-1.4.2.js'></script>
<script>
var jq142 = jQuery.noConflict();
</script>
0
votes

The site for RequireJS documents a method to configure jQuery to load with noConflict. This method allows you to require jQuery as "jquery" as you'd normally do even if you did not use noConflict. The configuration is as follows (quoted straight from the doc):

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 is as follows (also quoted straight from the doc):

// and the 'jquery-private' module, in the
// jquery-private.js file:
define(['jquery'], function (jq) {
    return jq.noConflict( true );
});

Loaded this way, the version of jQuery you ask RequireJS to load should not disturb any other jQuery version loaded before it.

However, there's one significant problem: anything loaded by RequireJS and which needs to access the jQuery version loaded by RequireJS must be a AMD module (i.e. it must use define and list in "jquery" in it dependencies). Otherwise, it'll use the version of jQuery loaded before RequireJS. Whereas when only one version of jQuery is loaded, you can use a shim in RequireJS' configuration to get such software to load, if you use the method above, a shim won't cut it here.

This line in Backbone, for instance, is problematic:

Backbone.$ = root.jQuery || root.Zepto || root.ender || root.$;

So you'd have to modify Backbone to define itself as an AMD module or find a version that someone has already packaged. (Like the one here.)