I've been messing around with TypeScript again for my game project and wanted a module loader to consume the single file produced by the TypeScript compiler. This time around I decided to use SystemJS and figured I'd share the lessons I learned along the way.
If you're interested in playing with the code, you can checkout this GitHub project I setup just for that reason.
I also posted about doing the same sort of thing with AMD and RequireJS complete with a GitHub sample project
Here's the gist of it. My project has the following requirements:
- Source code in TypeScript, organized in to multiple modules
- Load external modules into application as dependencies
- Transpile down to a single bundle file
- Load the bundle in the browser
It seems pretty straight forward, right? Plus, because I'm using TypeScript I figured this would be easy peezy lemon-squeezy with the TypeScript compiler and rich documentation.
As it turns out, it wasn't that simple.
Wait. Where's GulpJS?
It's in the sample project handling the transpiling the TypeScript through a task.
It's actually not required, but rather a convienience for keeping all my build tasks together. I just put it in the title, because it matches the previous post.
Problem 1: Using an External Module
I wanted to use Moment.js to help handle date objects with my code.
There were two parts to this:
- Getting it working in the development environment
- Getting it bundled up with SystemJS.
Using it in Development
I use Visual Studio Code, which is a great TypeScript development environment.
Normally, you would use the
@types collection of defintion files from the NPM which is wired up by default. For Moment, we need to break that.
The definition file for Moment is found in the library itself. Since I use NPM to handle all my dependencies, you just set this up in your
Then, in code, we import it.
import moment from "moment";
Remember: if your project is already using
@types definition files, you'll need to add that folder to the
typeRoots collection yourself.
Bundling it Up
Because we're using SystemJS, we need to do is configure it as a path to understand where to find the library when it gets referenced.
In the sample project, we do it in
script tag on the HTML page, but you can do this in wherever you end up doing your SystemJS configuration.
Problem 2: Loading the Bundle
Making a bundle is easy. Consuming the bundle is something different.
Making a Bundle
If you're interested in bundling your code into a single file with the compiler, you're limited to AMD or SystemJS modules. This is configured in the
tsconfig.json file included in the sample project with the module property. You can read more about it here in the TypeScript Handbook.
Consuming the Bundle
This is where I got stuck.
Now I have this fancy bundle, but I need to figure out how to consume it in my HTML page. The solution is pretty simple, but it took some research and some tinkering, but I got there.
Take a look at the
<body> take of the HTML file:
I blame myself for getting stuck considering this sort all documented well in the SystemJS documentation on GitHub. Either way, I had issues finding solid resources about using bundles. Hopefull this can help someone else in the future.