Question

In order for jQuery to hook onto require.js, jQuery has to be loaded after require.js. That works fine, but as soon as i include a jQuery plugin called BlockUI, which does some weird AMD stuff (see bottom of BlockUI source), i get a mismatch error. I know BlockUI is causing this because the mismatch error spits out the entire source, and everything works if i remove BlockUI. It doesn't matter if utilize require.js or not; just including the library is enough.

See this jsfiddle: http://goo.gl/4tYE7

Switch over to the Resources tab on the left, to verify that all scripts are loaded in the correct order. All good? Good, now open the console. POW! Blood everywhere!

I'm not sure if this is a Require.js or BlockUI bug (i'm betting BlockUI since it's a bit outdated), but is there any workaround for this? What is actually happening in the bottom of BlockUI? jQuery exposes itself as an AMD module at the bottom of the source, why does BlockUI do similar things?

I don't have much control over the loading of BlockUI because it's loaded by a Wordpress plugin (Jigoshop), so getting this to work is rather important.

Was it helpful?

Solution

How are you using BlockUI? Are you requiring it or using it as a dependency? Taken from the RequireJS site:

If you manually code a script tag in HTML to load a script with an anonymous define() call, this error can occur.

Also seen if you manually code a script tag in HTML to load a script that has a few named modules, but then try to load an anonymous module that ends up having the same name as one of the named modules in the script loaded by the manually coded script tag. Finally, if you use the loader plugins or anonymous modules (modules that call define() with no string ID) but do not use the RequireJS optimizer to combine files together, this error can occur.

The optimizer knows how to name anonymous modules correctly so that they can be combined with other modules in an optimized file. To avoid the error: Be sure to load all scripts that call define() via the RequireJS API. Do not manually code script tags in HTML to load scripts that have define() calls in them. If you manually code an HTML script tag, be sure it only includes named modules, and that an anonymous module that will have the same name as one of the modules in that file is not loaded. If the problem is the use of loader plugins or anonymous modules but the RequireJS optimizer is not used for file bundling, use the RequireJS optimizer.

http://requirejs.org/docs/errors.html

If you use jQuery and BlockUI as modules it will work just fine:

require.config({
    'paths': {
        'jquery': 'http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min',
        'blockUI': 'http://malsup.github.com/jquery.blockUI'    
    },
    'shim': {
        'blockUI': ['jquery']    
    }
})

require(['blockUI'], function(){
    // Don't return a value to the callback as it just augments the $.fn
    console.log($.fn.block);
    console.log($.fn.unblock);
});

Example - http://jsfiddle.net/Blink/ae4nr/

What is actually happening in the bottom of BlockUI? jQuery exposes itself as an AMD module at the bottom of the source, why does BlockUI do similar things?

It's a known technique for supporting AMD with plugins and such. Wrapping the code in a function means that the window.jQuery can be passed in if no AMD is present otherwise the function can be passed to define and then jQuery will be passed to it once it loads. Either way, all the plugin code cares about is receiving the jQuery object to use as $.

Defining 'jquery' as a path is a requirement of using it with AMD so the plugin author can safely assume that 'jquery' will be defined:

define(['jquery'], setup);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top