ES6 Modules and Typescript

The whole thing is still pretty crazy as of August 2016. If you want to develop your frontend with typescript, you’ll probably encounter all of those “things”:

bower, npm, node, grunt, gulp, typescript, tsconfig, tsc, transpile, es6, javascript2015, module, module loader, import, export, require, systemjs, amd, umd, commonjs, babel, traceur, browserify, webpack…

Those are just some things mixed together in a wild manner, but the sheer amount of tools & concepts is nuts.

Okay, so what’s the whole point anyways? You want to use typescript and this usually goes hand in hand with the import / export syntax. Import / export is from “es6” = “javascript2015”, but this javascript version is not fully supported by most browsers yet. And you don’t want to build your production app in a language that won’t run in most browsers. So what can you do? You can use something that does the following:

MAP ES6 to ES5

Who can do this? Babel, typescript and traceur for example. Forget about babel and traceur and use typescript.

But if you use import / exports in your code (i.e. modules) the es5 generated by typescript will not run by itself. Here you have two choices:

  1. Don’t use modules.
  2. Use a module loader.

Unfortunately there is no way around using a module loader, if you want to use import / export in your code. If you already have a large app, you have to think this through, as introducing modules implies quite a lot of refactoring. The rest of this article assumes you decided to use modules. A possible and not all-too-stupid choice for a module loader is SystemJS.

So, in summary what happened until now:

  1. ES6 has “cool new features you want to use”, but browsers don’t support them yet. (But probably you were kinda dragged into this by starting with typescript)
  2. In order to use es6 syntax today to develop a production ready app, we thus somehow need to map es6 to es5. Typescript does this for us.
  3. The es5 generated by typescript doesn’t run by itself, in case you are using modules (i.e. there is import / export in your code). In order to load those modules, you’ll need a module loader like SystemJS.

Here’s a minimal “app” that is built around those concepts:

index.html

<!DOCTYPE html>
<html lang="en">
 <head>
 <meta charset="utf-8">
 <title>Typescript Modules</title>
 
 <!-- get systemJS from somewhere -->
 <script src="https://code.angularjs.org/tools/system.js"></script>
 </head>
 <body>

 <script>
 // set our baseURL reference path
 System.config({
 baseURL: './'
 });

 // loads /js/main.js
 System.import('main-module.js');
 </script>

 Open your js console.
 </body>
</html>

main-module.ts

import {someVar} from "./some-es6-module.js"

console.log(someVar);

some-es6-module.ts

export var someVar = "Hello World";

tsconfig.json

{
 "compilerOptions": {
 "module": "system",
 "target": "es5"
 },
 "files": [
 "main-module.ts",
 "some-es6-module.ts"
 ]
}

To make it run:

  1. Put all those files into a folder or download them from https://github.com/bersling/minimal-typescript-es6-module-app/tree/master.
  2. Get the typescript compiler and run tsc.
  3. Start a server with python -m SimpleHTTPServer and see the app at 127.0.0.1:8000

Leave a Reply

Your email address will not be published.