Tuesday, June 21, 2016

Mixing Globals with ES6 Module Implementation

Typescript 1.8 adds the new jsconfig.json format. So now, when the compilerOptions.module field is set to 'system' or 'amd' and compilerOptions.outFile is also set, typescript will bundle all of my modules, transpiling import/export polyfills. But it incudes no implementation for those polyfills. I could use SystemJs, but that is another external, and it's overkill - I only need to use module syntax internally, to see other modules in the same bundle.

My project consumes globals, such as PIXI.js. And to expose my API to scala.js, my library needs to be a global. But within my library, I want to use all the new es6 features, including import and export.

So my jsconfig.json looks like this:

{
    "compilerOptions": {
        "target": "es6",
        "module": "amd",
        "rootDir": "src",
        "outFile": "js/app.js"
    },
    "files": [
        "src/define.js",
        "src/lib/lib.js",
        "src/lib/shapes/Circle.js",
        "src/lib/utils/functions.js"
    ]
}

Typescript normalizes the interface, so no parameter checking is needed. For amd modules, the define
function is less than 10 lines of code:
After running tsc, the outFile js/app.js:

var define = (function (modules) {
    return (name, deps, callback) => {
        modules[name] = { id: name, exports: {} };
        let args = [(name) => modules[name].exports, modules[name].exports];
        for (let i = 2; i < deps.length; i++)
            args.push(modules[deps[i]].exports);
        callback.apply(modules[name].exports, args);
    };
}({}));
define("lib/shapes/Circle", ["require", "exports"], function (require, exports) {
    "use strict";
    //------ lib.js ------
    class Circle {
        constructor(radius) {
            this.radius = radius;
        }
    }
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.default = Circle;
});
define("lib/utils/functions", ["require", "exports"], function (require, exports) {
    "use strict";
    //------ lib2.js ------
    exports.sqrt = Math.sqrt;
    function square(x) {
        return x * x;
    }
    exports.square = square;
    function diag(x, y) {
        return exports.sqrt(square(x) + square(y));
    }
    exports.diag = diag;
});
define("lib/lib", ["require", "exports", "lib/shapes/Circle", "lib/utils/functions"], function (require, exports, Circle_1, functions) {
    "use strict";
    /**
     * Re-export it all to a namespace-like object hierarchy
     */
    window.lib = {
        shapes: {
            Circle: Circle_1.default
        },
        utils: {
            functions: functions
        }
    };
});


1 comment:

  1. Hi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me.. I am a regular follower of your blog. Really very informative post you shared here. Kindly keep blogging. If anyone wants to become a Front end developer learn from ES6 Training in Chennai . or learn thru ES6 Training in Chennai. Nowadays JavaScript has tons of job opportunities on various vertical industry. ES6 Online Training from India

    ReplyDelete