2

I'm putting together a framework using requireJS with a CDN version of jQuery (as is now the recommended approach) and having some issue when optimizing the code. The output is namespaced and I'm specifying that each module use a private version of jquery as outlined in the documentation:

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 );
});

The problem I'm seeing after optimization is that "jq" is undefined in the "jquery-private.js" file.

Any ideas? I've tried setting jq = $ but that seems to destroy the global.

Thanks.

2
  • It works fine if you take away the map config and don't try to make it a private version? Commented Jul 12, 2013 at 15:02
  • Yes, it works fine without the map config Commented Jul 12, 2013 at 20:10

2 Answers 2

5

Here is what I did to get the jQuery CDN & optimization sample linked from the RequireJS jQuery Instructions page to work with the Mapping Modules to use noConflict section that you pasted in your original question.

1 - Forked the sample

2 - Created file www/js/lib/jquery-private.js with this content

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

3 - Modified www/js/app.js to paste the map section so the require.config now looks like this:

requirejs.config({
    "baseUrl": "js/lib",
    "paths": {
      "app": "../app",
      "jquery": "//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min"
    },
    map: {
      '*': { 'jquery': 'jquery-private' },
      'jquery-private': { 'jquery': 'jquery' }
    }    
});

4 - Modified www/js/app/main.js to use jqlocal instead of $ (just to prove to myself that it's not the global jQuery:

define(["jquery", "jquery.alpha", "jquery.beta"], function(jqlocal) {
    jqlocal(function() {
        jqlocal('body').alpha().beta();
    });
});

5 - Changed to the tools folder and ran:

node r.js -o build.js

6 - Changed to the www-build folder that was created and ran servedir (doesn't really matter what web server but that's what I use for dev)

7 - Browsed to the local address & port number of the app (in my case http://localhost:8000/app.html) and saw:

Alpha is Go!

Beta is Go!

You can see the end result here

Sign up to request clarification or add additional context in comments.

1 Comment

In case it's not obvious, that paths value of 'jquery' is vital in the RequireJS docs. I ran into this myself and beat my head against a wall for about half an hour. If it's not there, jq will be UNDEFINED in the jquery-private.js module.
0

To get this working I changed the way I was using Require (possibly how I should have been doing it all along). This information might prove useful to others, so I thought I'd put it out there.

Previously I was specifying any dependencies in the defined module:

define( [ "dep1", "dep2", "jquery" ], function( var1, var2, jq ) {

This worked fine initially, but failed when optimized. I moved the dependencies to the require function call including this module and it then started to work OK both pre and post optimisation, with jquery being used privately:

require( [ 'jquery', 'dep1', 'dep2' ], function( jq, var1, var2 ) {
    formValidator.formValidationInit( jq( el ) );
});

I wouldn't have thought this would have made a difference, but it seemed too.

It is also worth noting that I had to change the jquery-private file as it was still throwing up an issue concerning "jq" not being defined. I am now setting jq equal to the global $ and returning it so it can be used pivately:

define(['jquery'], function () {
    var jq = $;
    return jq.noConflict( true );
});

2 Comments

This is the absolutely wrong way to use requireJS. Instead of defining a module, all you're doing is declaring a require load -- might as well not use requirejs. 'jq' is UNDEFINED probably because you're missing the 'jquery' attribute in the paths in the config (see explunit's answer). This piece of non-trivial information is missing in the requireJS documentation.
Thanks Robert - It didn't feel right, but I was having issues compiling the code and using private jquery. After reading this, I have gone back and refactored my code and it's working as expected. Essentially I removed the modules from the require calls back into the module definitions. Although missing from my initial post, I did have the jquery path listed, but have also seen that this trivial info is missing from the documentation. Thanks again for your responses

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.