Alternative output AMD-based external modules

Topics: General
Jan 19, 2014 at 1:55 PM
Hello,

I was wondering if the TypeScript team considered alternative output for AMD-based TypeScript modules.

For example this TS file:
import dep1 = require('./dep1');
import dep2 = require('./dep2');

export function x() {
    return dep1.x() + dep2.x();
}
when compiled using --module amd flag produces following JavaScript file:
define(["require", "exports", './dep1', './dep2'], function(require, exports, dep1, dep2) {
    function x() {
        return dep1.x() + dep2.x();
    }
    exports.x = x;
});
The dependencies are grouped together into an array.

Require.js provides a sugar syntax that IMHO makes the JavaScript output more similar to the TypeScript output making it also more readable.

The example JS output above would look like this using sugar syntax:
define(function(require, exports) {
    var dep1 = require('./dep1');
    var dep2 = require('./dep2');

    function x() {
        return dep1.x() + dep2.x();
    }
    exports.x = x;
});
Note that it still works the same way as the array syntax as require.js scans the function definition and extracts require calls before executing the function. When using optimizer it will actually insert the array of dependencies at build time.

More details are here: http://requirejs.org/docs/whyamd.html#sugar

The sugar syntax could also be a way to resolve issues with loading things outside TypeScript imports (require.js plugins, for example templates):
import dep1 = require('./dep1');
import dep2 = require('./dep2');

declare function require(name: string): any;
// or predefine it when using external modules - it's already in scope!

var template: string = require('text!template.html');

export function x() {
    return dep1.x() + dep2.x();
}
would turn into:
define(function(require, exports) {
    var dep1 = require('./dep1');
    var dep2 = require('./dep2');

    var template = require('text!template.html');

    function x() {
        return dep1.x() + dep2.x();
    }
    exports.x = x;
});
and the need for // <amd-dependency> disappears because require.js grabs all require(constant string) calls at run- or build-time. Predefining require function in lib.d.ts would make working with require.js plugins a truly seamless experience.

The only disadvantage that I see may be incomatibility with other AMD loaders that I don't know of (as I work only with require.js).