Angular, TypeScript, SystemJS, and Browser Cache

I was writing a small app in Angular 2 in TypeScript with the on-the-fly transpiling by SystemJS. I needed to implement a router that would switch between the Home and ProductDetail views in a single page app.  The root component had two links and was supposed to render either Home or ProductDetail components depending on which link the user clicks. Angular 2 offers a pretty elegant syntax for this:


@Component({
    selector: 'basic-routing',
    directives: [ ROUTER_DIRECTIVES], 
    template: `<a [router-link]="['/Home']">Home</a>
              <a [router-link]="['/ProductDetail']">Product Details</a>
              <router-outlet></router-outlet>` 
})
@RouteConfig([
    {path: '/',        component: HomeComponent, as: 'Home'}, 
    {path: '/product/', component: ProductDetailComponent, as: 'ProductDetail'  } 
])
class RootComponent{}

Configure the router to map the component to a URL, use property binding in the form of [router-link], and specify the router outlet, where the content of one or the other component should be rendered. Nice and easy, isn’t it? Then I created a HomeComponent to render the text ‘Home Component’ , copy-pasted the code into ProductDetailComponent and started the app in the browser.

Running the app properly rendered the text Home Component, but when I clicked on the second link, nothing happened – the text Home Component remained in the browser window. Opened the code of the ProductDetailComponent. Oops… Forgot to change the text for rendering while copy-pasting – it still had ‘Home Component’. No biggies. Replaced it with ‘Product Detail Component’ and re-ran the app. Nothing changed. I still see Home Component no matter what link I click.

So what do we do with this nice syntax with Angular binding and TypeScript annotations? There is nothing to debug there. We need to debug the actual ES5 code that runs in the browser. Here’s the snapshot of my application window (on the left) after I clicked on the Product Detail link (Chrome Dev Tools panel is on the right):

ts1

Note that Angular router properly formed the URL for the product view. The template property in the file product.ts has the right content: ‘Product Detail Component’. Now let’s take a look at the content of the file product.ts!transpiiled, which was auto-generated by SystemJS:

ts2

This file was not regenerated and still has the ‘Home Component’ in the template property! Apparently, changing the string content is not a good enough reason for SystemJS to re-run the TypeScript transpiler and the browser used its cached version. Running the same example in FireFox worked as expected – its cache was clean so fresh ES5 files were generated by SystemJS.

Chrome Dev Tools has an option Disable Cache while Dev Tools open, and this would clear the cache on the page refresh. But if you want the browser cache to be refreshed even if the Dev Tools are not open, add the following lines between the head tags in your HTML file:

  <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
  <meta http-equiv="Pragma" content="no-cache">
  <meta http-equiv="Expires" content="0">

Manning opened the MEAP program for our upcoming book “Angular 2 Development with TypeScript”, where JSPM, SystemJS and TypeScript development is covered in greater details.

Advertisement

8 thoughts on “Angular, TypeScript, SystemJS, and Browser Cache

    1. Currently I use SystemJS, which does on-the-fly compilation when the app is loaded to the browser.
      If I had to deploy the app to prod, I’d run the compilation script for all .ts files to eliminate a 2-second delay caused by on-the-fly compilation.

      Having said that, I’m still looking for the fastest workflow during development.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

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

Facebook photo

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

Connecting to %s