/taml

Tiny Asynchronous Module Loader

Primary LanguageJavaScriptOtherNOASSERTION

Taml

Tiny Asynchronous Module Loader

Why

I like the system described in the Asynchronous Module Definition (AMD) API specification, but instead of having a "for browser" version that fetches scripts separately, I wanted to just cat the scripts together and have everything loaded at once at runtime.

Yes, I've reinvented the wheel. But look, it's less than 200 lines.

What

taml.js is a Javascript script that defines a global function, define, that can be used to define modules in a manner similar to the AMD specification. define additionally exposes two properties:

  • define.load(moduleName?) returns a Promise that loads the optionally specified module and its dependencies and then returns the loaded module object. If no module name is specified, then the Promise loads all modules and returns an object mapping fully qualified module names to modules.
  • define.modules is an object of all loaded modules, keyed by fully qualified name.

taml.js differs from AMD in a couple of notable ways:

  1. The special module names exports, require, and module are not supported.
  2. Modules are not loaded as soon as possible (once all their dependencies have been defined). Instead, no module is loaded until define.load is called.

These differences in design are to maintain the simplicity of the implementation. Compatibility with other libraries is not a goal (for that, just use require.js).

How

Execute the contents of taml.js in your Javascript environment. Then modules can be defined using define, one invocation per module. For example:

<script src="taml.js"></script>

<script>
define('foo', ['util/bar', 'util/stuff'], function (Bar, Stuff) {
    const moduleObject = {
        doSomethingAmazing: () => console.log('hello, world!')
    };
    // ...initialization code...
    // ...
    return moduleObject; 
});

define('util/stuff', ['./bar'], function (Bar) {
    // ... etc...
});

define('util/bar', function () {
    // ... etc...
});

define('util/odd', ['../foo'], function (Foo) {
    // ... etc...
});

define.load().then(modules => {
    // "main" function goes here...
    // e.g.
    modules.foo.doSomethingAmazing();
});

</script>