Tags

, , ,

AMD Loaders Rock!

I have been using require.js (an AMD loader) to do allot of client side development and can’t really imagine starting any decent size project (App) without it.  It allows you to break up your code into modules that are loaded along with their dependencies (other modules). This design patters allows for greater code maintainability as well as improve overall application development by abstracting away the dependency loading mechanism (think deep dependencies: module A is depended on Module B, but B is dependent on C, D, E…). The patterns also encourages keeping the global scope clean and ensuring that all variables are defined to only the executing scope – a pattern that everyone should follow – regardless of AMD – so that conflicts with other modules/libraries/frameworks are not introduced.

A Private Version of jQuery

One of the needs I came across in the last week was how to load a specific version of jQuery via require.js and keep that version private. I’m familiar how to do this in a non-AMD way, but I wanted keep to the AMD design pattern. The app I was developing was going to be added to a page that already had jQuery loaded, so I needed to ensure I did not interfere with it or overwrite it. jQuery itself already supports AMD loaders, but even in the instances where it detects an AMD loader on the page, it still adds two variables to the global space: jQuery and $. The answer obviously is to use  jQuery’s noConflict() method.

The documentation over at require.js provides an entire chapter on how to work with jQuery, including how to obtain a private version of it by using jQuery’s noConflict() method, which is the ideal method for when wanting to load jQuery from a CDN.  I was hosting my own copy of jQuery for this project and thus found the approach detailed there to be overkill. As it turns out, there is a simpler (IMO) setup if you are going to host the copy of jQuery: wrap it in a define() statement and immediately call noConflict().  Here is the content of my jquery.js file:

define(function(){

    // jQuery's code here

    return jQuery.noConflict(true);

})

So this includes the jQuery code inside of the module and immediately calls jQuery.noConflict(true), which essentially reverts the jQuery and $ global variables to their prior values (if they were set), thus ensuring I don’t interfere with any other version already loaded on the page.

Like I said: if you are loading jQuery from a CDN or a location where you don’t have control over the file’s content, then the instructions detailed in the require.js documentation should be followed.

What About jQuery Plugins

One thing I realized, as I was implementing the above code, is that most jQuery plugins (mine included) are not AMD aware. I have not tried (will soon), but I think require.js provides a mechanism for handling that as well. And then again: if hosting those locally along with your App, then the following should also work:


define(['jquery'], function(jQuery){

    // jQuery Plugin code here. Example:
    (function($){

        ...

    })(jQuery);

})

 

One of the tasks I took way from this effort was to make my jQuery plugins AMD aware the next time I make a change to them.