Building heterogeneous TypeScript libraries

Published: 2012-09-21

A technique for compiling one or more TypeScript source files to a single JavaScript library file that can be used in both the browser and by Node.js applications.



By way of example

Our library source consists of a single TypeScript module called Lib spread across multiple source files (lib1.ts and lib2.ts) that exports a public API:

lib1.ts

module Lib {
  export function f() {}
}

declare var exports: any;
if (typeof exports != 'undefined') {
  exports.f = Lib.f;
}

lib2.ts

module Lib {
  export var v = {foo: 42};
}

declare var exports: any;
if (typeof exports != 'undefined') {
  exports.v = Lib.v;
}

The important part is conditionally assigning the public API objects to exports. This code must be placed at the end of the source files outside the module declaration. exports is defined by CommonJS compatible loaders such as Node’s. This code has no effect in the browser because exports is not defined.

The source file are compiled to a single JavaScript library lib.js using the TypeScript compiler:

tsc --out lib.js lib1.ts lib2.ts

lib.js

var Lib;
(function (Lib) {
    function f() {
    }
    Lib.f = f;
})(Lib || (Lib = {}));
if(typeof exports != 'undefined') {
    exports.f = Lib.f;
}
var Lib;
(function (Lib) {
    Lib.v = {
        foo: 42
    };
})(Lib || (Lib = {}));
if(typeof exports != 'undefined') {
    exports.v = Lib.v;
}

lib.js file now can be included on an HTML page with:

<script type="text/javascript" src="lib.js"></script>

Or in a Node.js application with:

var Lib = require('./lib.js');

The APIs are accessed via the module name e.g. Lib.f(), Lib.v.

Note

Multi-file “open” modules are not truly open — you must export any module objects that require access across file boundaries. This could force you to expose objects in the public browser API that should otherwise be module private.

Explanatory notes

TypeScript can emit CommonJS modules directly by prefixing module with the export keyword, but there are two problems with this:

  1. The generated code is not browser compatible.
  2. Exported (external) modules must reside in a single source file (they are not open).

References

About these ads

One Response to “Building heterogeneous TypeScript libraries”

  1. Robbie McDiarmid Says:

    Thanks a lot. I’ve been looking all over for a solution like this.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: