Solving the Javascript include problem

One problem facing Javascript developers is this: Your class model is spread across multiple Javascript source files. Class A depends on B, C and D. You are now faced with the problem of including the correct Javascript source files in all applications which use class A.

In ordinary HTML/XUL, you have a series of <script src> tags in all applications using class A. When class A starts requiring class E, you have to edit all HTML/XUL files again and manually include class E. And of course, it is very likely that you will miss one place or two which causes parts of the application to break. This is a problem which should be solved at the language level, but is not addressed at all so far in ECMAScript.

One quite elegant solution in the XUL world is using overlays.

Overlays are XML fragments which can be included from multiple source files. Their original purpose is extending XUL pages by merging XUL fragments into existing elements. For example, if you have a XUL page containing:

<groupbox id="foo">
    <caption label="foo"/>
</groupbox>

And a XUL overlay:

<groupbox id="foo">
    <textbox id="bar"/>
</groupbox>

Mozilla will merge the contents of the XUL overlay into the real groupbox, so it looks like this:

<groupbox id="foo">
    <caption label="foo"/>
    <textbox id="bar"/>
</groupbox>

Thus, overlays can be used to store repeatedly-used XML structures in a central place. Now, we can apply this to the problem described above: Defining all dependent JS source files once and reusing that definition. Inside the overlay, we create a simple <box> which contains all relevant includes.

Here is a real-life example:

<?xml version="1.0" encoding="ISO-8859-1"?>
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
    <box id="classdm">
        <script src="../../ge/common/ge_errors.js"/>

        <script src="../common/js/dm_akte.js"/>
        <script src="../common/js/dm_address.js"/>
        <script src="../common/js/dm_damage.js"/>
        <script src="../common/js/dm_ubtl.js"/>
        <script src="../common/js/dm_vehicle.js"/>
        <script src="../common/js/dm_ra_agreement.js"/>
        <script src="../common/js/dm_lv_info.js"/>
        <script src="../common/js/dm_breakdowns.js"/>
        <script src="../common/js/dm_address.js"/>

        <script src="../../pa/common/pa_address.js"/>

        <script src="../../lv/common/lv_insurances.js" />
        <script src="../../lv/common/lv_rvcs.js"/>
    </box>
</overlay>

Now, applications wanting to use "classdm" can easily do so:

<?xul-overlay href="../common/dm_overlays.xul"?>
...
<page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
    <box id="classdm"/>
</page>

And that's it. Without resorting to DOM hacks or XPConnect-privileged script loaders, we can bundle Javascript includes and use the bundle in multiple places.

Trackbacks

    No Trackbacks

Comments

Display comments as (Linear | Threaded)

  1. Wolfram Kriesing says:

    This problem of including JS files was very nicely by dojo. Thats actually what one wants, see http://manual.dojotoolkit.org/dojo.html#root-dojo-methods
    There you can do stuff like
    dojo.require("my.string");
    a nice side effect is that you get a nice, kind of module/namespace handling. well done imho, worth a try.
    _And_ dojo is not targeted to client side js only, so using it for xul should work quite well.

  2. Sascha Schumann says:

    Well, the dojo-interface looks nice. But I suggest you take a look beneath the shiny hood.

    Dojo violates the "degrade nicely" paradigm. If the user agent does not support XMLHttpRequest or if it is deactivated, your required scripts won't load. Instead, Dojo will happily throw an exception in your face.

    Add to that that dojo's cache buster will very likely render your static Javascript files uncacheable.

    Also, I suggest taking a look at the Dojo source code in general -- the files I looked at need some cleanup urgently. The current version (0.2.2) shows quite clearly that Dojo is far from being release-quality.

  3. Wolfram Kriesing says:

    Yep, I am looking very much into the dojo source code and as I stated here: http://wolfram.kriesing.de/blog/index.php/2006/dojo-first-hugs I agree with you, dojo is not final.
    But it is on a good way, imho. As soon as IE7 will be out and supporting XmlHttpRequest natively (not via ActiveX) the loading using this function should be less of an issue.

  4. Sascha Schumann says:

    XMLHttpRequest is suitable for highly dynamic processes -- I am not positive that loading JS source files is such a dynamic process. I view the script-tag more as some kind of linking process where you statically bind a resource into your program, similar to C.

    In the case of Dojo, it would probably be more efficient to load all abstractions in one big sweep and instantiate the correct one at run-time -- rather than starting a series of synchronous (slow and expensive especially in Mozilla) XMLHttpRequests after the page has loaded.

    As such I am convinced that following the Dojo approach won't lead to better applications -- only to slower, less portable ones.

  5. Sebs says:

    using php a simple include in the template can help you too.


    p.s. more xulblog please ;-)

  6. Wolfram Kriesing says:

    The dojo approach to speed issues and also for the require() problem is nicely explained here: http://dojo.jot.com/FAQ#Performance

  7. Michael Lee says:

    Hi all,
    Looks like this discussion fizzled a while back. If it's still an issue or a better solution is still needed take a look at AJILE over at:

    htp://ajile.iskitz.com/

    It's a JavaScript library created solely for the purpose of dynamically loading/importing JavaScript modules. It focuses on simplifying and automating the include process and makes it easy to define script dependencies without depending on the XMLHttpRequest object.

    -Michael


Add Comment


Standard emoticons like :-) and ;-) are converted to images.

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA 1CAPTCHA 2CAPTCHA 3CAPTCHA 4CAPTCHA 5