Custom loader functions

Some libraries, such as the Google Ajax APIs, have their own systems for loading code on demand that involve more than simply knowing the path to a script file. Our package system allows you to specify packages that use a loader function rather than a path to load themselves; the function should take a callback and call it when the library in question is done loading. For example, here’s how you’d incorporate Google Maps into your library:

JS.packages(function() { with(this) {
    file('http://www.google.com/jsapi?key=MY_GOOGLE_KEY')
        .provides('google.load');

    loader(function(cb) { google.load('maps', '2.x', {callback: cb}) })
        .provides('GMap2', 'GClientGeocoder')
        .requires('google.load');
}});

The callback (cb) is a function generated by the package system that continues to load and run dependent code once the custom loader has finished its work. If you don’t call cb (or pass it to a function that will call it for you as above), code that depends on this library will not run.

JS.packages also provides post-load setup hooks that let you run some code after a file loads. For example, a strategy for loading YUI3 might involve loading the seed file, creating a new global instance of the library, then using YUI’s own loader functions to load further modules. Some sample code:

JS.packages(function() { with(this) {
    file('http://yui.yahooapis.com/3.0.0pr2/build/yui/yui-min.js')
        .setup(function() { window.yui3 = YUI() })
        .provides('YUI', 'yui3');

    loader(function(cb) { yui3.use('node', cb) })
        .provides('yui3.Node')
        .requires('yui3');
}});

Loader functions can also be used to generate library objects that are expensive to create without necessarily loading code from external files. Just remember to call cb yourself when the generated object is ready:

JS.packages(function() { with(this) {
    loader(function(cb) {
        window.ChocolateFactory = new WonkaVenture();
        // Perform other expensive setup operations
        cb();
    })
    .provides('ChocolateFactory');
}});