Tired of waiting for TypeScript compilation?

Relative template URLs for Angular2 components

When you write an Angular2 Single Page Application you need the TypeScript compiler to create at least ES5 JavaScript code to be able to run your SPA in a modern browser. If you take a closer look at the resulting code generated by the TypeScript compiler with at least version 1.8.2 you should see that there is a local variable called __moduleName which filled with the id property of the second parameter of the inner function:

System.register(['angular2/core'], function(exports_1, context_1) {
    "use strict";
    var __moduleName = context_1 && context_1.id;
    var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
...

Unfortunately, this variable was always undefined. The reason for this could not be found in the TypeScript compiler's code - it is innocent (for this time, boy). But let's take a closer look at the module system Angular is using. Yes! Starting with SystemJS 0.19.19 life came to this variable. With that version (the most recent version is already 0.19.25 by time of writing of this article) the second parameter was finally provided and the variable was now set to the URL of the current module. Like in my sample it contains the following:

http://localhost:8000/app/components/app/app.js

But what can you do with this information? The key to happiness is to take this value and set it on the moduleId property of the @Component decorator:

@Component({
    moduleId: __moduleName,
    selector: 'my-app',
    templateUrl: 'app.html',
...

To satisfy the TypeScript compiler you first need to declare it as a string right at the beginning of our file:

declare var __moduleName : string;

That was easy. You may already spotted that I put a relative URL into the templateUrl property. How could this work? This is now possible as Angular is using the value you set on moduleId to resolve any relative URLs you may use either in templateUrl or even in styleUrls. And by saying "relative URLs" I mean true relative URLs like "../other.html" (but you may not do this, as a component should be together with it's template etc. at one place).

Finally, no more hassle when you move components between folders (but keep watching the import statements). Good guy, SystemJS.

Comments

Feed You can follow this conversation by subscribing to the comment feed for this post.

The comments to this entry are closed.