I've been tinkering with TypeScript lately and was trying to setup my project to compile all of my modules into a single file, which would then be used in an HTML page. Maybe this is obvious to the more experienced TypeScript developer, but I had made a number of false assumptions while trying to get this to work.
This post will walk you through what I did to setup my build and get it working in an HTML page.
You can follow along at home with the source code which I've put up on GitHub
Modular TypeScript
My project is starting out simple, with a single module and a couple of different "Apps" that will use the module. Module in TypeScript is extensively documented in the TypeScript Handbook, so if you're not familiar with this I would suggest reading up on it as it's pretty awesome once you start using it.
In any case, here's my code:
1 | // ModuleOne.ts |
1 | // ModuleTwo.ts |
1 | // App.ts |
I have a single application that is using two modules. Plain and simple. Next up, I compile my code into a single file, then reference that in my HTML, and done like dinner.
...or so I thought.
The --outFile
Parameter
Reading through the doucmentation about TypeScript compilation, I found the --outFile
or --out
parameter in the documentation. I immediately assumed that I was done, as I would simple choose my ES target, select the type of modules I would like, and presto.
That wasn't the case.
Being a person who likes modern JavaScript, I had originally opted to output ES6 compatible code complete with the new modules.
This is was my first mistake.
I found was that when I compiled, I would get a single output file but it would be completely blank. No error, but just an empty file. This is expected behaviour, as the --outFile
option only supports commonjs and amd. That meant no ES6 or even ES2015 modules for my project, which is probably for the best considering how few web browsers in the wild actually support ES6 modules as of this writing.
In the end, I decided to go with AMD modules as I had some experience with RequireJS.
Now, when I try to compile again it works as expected! One big JavaScript file ready to go.
...sort of.
Using My Compiled TypeScript
Somewhere along the line, I assumed that whatever JavaScript file I compiled would only need me to add a <script>
tag reference to point to it like any other JavaScript file.
This was my second mistake, albeit a pretty silly one.
AMD modules have always needed RequireJS to load properly. That's the purpose for RequireJS. Maybe I had assumed the TypeScript compiler would embed this library or something, but whatever my reasoning it was wrong. I needed to include a data-main
file, as you do with every RequireJS example.
I added this to my HTML file, along with the RequireJS library in my project:
1 | <script data-main="main" type="text/javascript" src="lib/require.js"></script> |
Then, my data-main
file goes something like this:
1 | // main.js |
I'm not going to go into the details here, but my paths
object in the requirejs.config
is pointing App
to our outputted file. We use this in our main function and point our compiled modules to the MyApp
object. We then call the start()
function on our exported class and we are off to the races.
When we run the application, we see the following in the JavaScript console.
Details on Compilation
I skipped that part on purpose, because I don't use the TSC compiler directly. Rather, I use gulp-typescript
with a tsconfig
file to compile my TypeScript and create sourcemaps for them. All of this is detailed on the package page, but I'll include my gulp task to make sure you have all the details in one place.
You're welcome. ;)
1 | var tsProject = ts.createProject('tsconfig.json'); |
Oh, and here's my tsconfig.json
file too.
1 | { |