JavaScript Module Loading

The Core.Web.Library namespace provides tools for dynamically loading JavaScript modules into a document. It is capable of loading multiple modules at a time, initializing them in a specified order, and firing a notification event upon their availability.

The simplest use of this API is to invoke Core.Web.Library.exec(). This function takes an array of library URLs and a function reference as its two parameters. The libraries will be loaded, in order, and then the function will be executed. The provided function may be a method specific object by using Core.method(). The exec() method may return immediately (before the modules have been loaded).

The following code demonstrates the use of exec(). It will load two JavaScript modules, "Alpha.js" and "Beta.js", and then invoke a method:

Core.Web.Library.exec(["lib/Alpha.js", "lib/Beta.js"],
        Core.method(this, this._ready));

The Core.Web.Library namespace will remember which modules have already been loaded. If you were to invoke the above again at a later time, it will not reload any modules which have already been installed.

Using Dynamic Module Loading

Dynamic module loading can enable you to break up an application into several modules, such that code is only loaded when it is required. This can considerably boost the start up time of small-to-medium applications and makes larger JavaScript applications possible and practical.

In a large JavaScript application, it can make sense to define groups of modules in a single place, and then always use Core.Web.Library.exec() when invoking code in a different module. For example, one might create a "modules" namespace as follows:

FooApp.Modules = {

    MODULE_USER: [ 
        "lib/extras/Application.TransitionPane.js",
        "lib/extras/Render.TransitionPane.js",
        "app/Wizard.js", 
        "app/User.js"
    ],
    
    MODULE_EDITOR: [
        "lib/echo/Arc.js",
        "lib/extras/Application.ColorSelect.js",
        "lib/extras/Render.ColorSelect.js",
        "lib/extras/Application.RichTextArea.js",
        "lib/extras/Render.RichTextArea.js",
        "app/Editor.js"
    ]
};

A method in the "root module" of an application that wishes to communicate with the "user module" of the application might then look like this:

    _processCreateAccount: function(e) {
        Core.Web.Library.exec(FooApp.Modules.MODULE_USER, Core.method(this, function() {
            var dialog = new FooApp.User.CreateAccountDialog();
            this.add(dialog);
        }));
    }