Aurelia with TypeScript in Visual Studio Code on ASP.NET 5

This article covers setting up an Aurelia project in Visual Studio Code running ASP.NET 5 to serve the pages and using TypeScript, instead of the default Babel es6 transpiler.
There are a few examples on the web on how to do this, but none felt like a smooth way of doing it in Visual Studio Code. So here is a shot at making it as easy as possible to get started with Aurelia in VS Code using TypeScript!

Versions Disclaimer

Check at the bottom of the article for a lengthy description of versions for all frameworks/tools used during the writing and testing of this post.

Prerequisites

There are a few things that are assumed, in this article, that you have installed on your system already.
These are: Visual Studio Code, DNVM/DNX (ASP.NET 5), Yeoman with the ASP.NET generator and Node.
If you want to follow along with the code examples, you should install them now if you haven’t already got them installed.

Creating a new ASP.NET 5 project

Open your command prompt of choice and position in a directory where you want to create the project.
Create a new project by entering yo and then selecting the Aspnet generator. When given the choice, select Empty Application and name your new app.
This will create a fairly empty ASP.NET 5 project for us that we can use.
First of, position in the directory that just got created for your app via the command prompt.

Installing jspm

So, what is this “jspm”? Jspm is the module loader that Aurelia uses. Read more about it here.
If you haven’t got jspm installed on your dev machine, it’s time to do that.
Installing jspm is done with npm from your command prompt, to install it globally on your machine, enter the following:
npm install jspm -g

Configure jspm

After installing it, it’s time to setup jspm.
Positioned in the root folder of the project, type:
jspm init
A number of questions will be asked now, answer according to the examples below. The questions with nothing written after them above is using the default, thus just hit return to go to the next one.

  1. Package.json file does not exist, create it? [yes]:
  2. Would you like jspm to prefix the jspm package.json properties under jspm? [yes]:
  3. Enter server baseURL (public folder path) [./]:wwwroot
  4. Enter jspm packages folder [wwwroot\jspm_packages]:
  5. Enter config file path [wwwroot\config.js]:
  6. Configuration file wwwroot\config.js doesn’t exist, create it? [yes]:
  7. Enter client baseURL (public folder URL) [/]:
  8. Do you wish to use a transpiler? [yes]:no

Regarding the choice to NOT use a transpiler and set it up here I’ll delve deeper in to that at the end of the article.

Setup ASP.NET 5

Now it’s time to start using Code πŸ™‚
Open VS Code by typing “code .” in the prompt.
Open the project.json file and add a reference under to dependencies section to:
"Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final"
Now edit the Startup.cs file and modify the Configure method like this:

        public void Configure(IApplicationBuilder app)
        {
            app.UseIISPlatformHandler();
            app.UseStaticFiles();
        }

This will enable our ASP.NET server to serve static files.

Now, add a new html page to the wwwroot folder, name it index.html:

<!DOCTYPE html>
<html>
	<head>
		<title>Aurelia + TypeScript + ASP.NET 5</title>
	</head>
	<body aurelia-app>
		<script src="jspm_packages/system.js"></script>
		<script src="config.js"></script>
		<h1>Hello World!</h1>
	</body>
</html>

Now go to the command line, position in the root of the project and first do a package restore (if you haven’t already done that from within VS Code) then start up ASP.NET 5 with:
dnu restore
dnx web

Open a browser and enter
http://localhost:5000/index.html
You should now be served with a page having only a heading saying: Hello World!
If everything works so far, it’s time to get on with the fun stuff πŸ˜€

Installing Aurelia

Now we need to install Aurelia and Corejs. In the command window, install the needed Aurelia bits with jspm by entering:
jspm install aurelia-framework
jspm install aurelia-bootstrapper
jspm install core-js

After a short while you’ll hopefully see an Install complete message (if not, a tip can be to check your GitHub download rate).

Setting up TypeScript compilation with Gulp

First we need to install a couple of npm packages. Open the package.json file in the root of the project. We need to add references to Gulp, TypeScript, Gulp-TypeScript and Merge. Edit the package.json like this:

{
  "version": "1.0.0",
  "name": "Aurelia_HelloWorld",
  "private": true,
  "devDependencies": {
    "typescript": "^1.6.2",
    "gulp": "^3.9.0",
    "gulp-typescript": "^2.9.2",
    "merge": "^1.2.0"
  },
  "jspm": {
    "directories": {
      "baseURL": "wwwroot"
    },
    "dependencies": {
      "aurelia-framework": "npm:aurelia-framework@^1.0.0-beta.1.0.2"
    }
  }
}

Now we a config file to tell the TypeScript compiler how to behave, and a file describing the Gulp tasks. But first, add a file in the root and name it tsconfig.json, this file details the behavior of the TypeScript compiler:

{
	"compilerOptions": {
		"emitDecoratorMetadata": true,
		"experimentalDecorators": true,
		"noImplicitAny": false,
		"noEmitOnError": true,
		"removeComments": true,
		"noExternalResolve": false,
		"declarationFiles": true,
		"target": "es5",
		"module": "amd",
		"sourceMap": true
	}
}

Now it’s time to define our Gulp tasks, create a new file in the project root, name it gulpfile.js:

var gulp = require('gulp'),
    ts = require('gulp-typescript'),
    merge = require('merge');

var webroot = "wwwroot";

var paths = {
    tsSource: './AureliaLogic/**/*.ts',
    tsOutput: "./" + webroot,
    tsDef: "./typings/"
};

var tsCompilerConfig = ts.createProject('tsconfig.json');

gulp.task('ts-compile', function () {
    var tsResult = gulp.src(paths.tsSource)
        .pipe(ts(tsCompilerConfig));

    return merge([
        tsResult.dts.pipe(gulp.dest(paths.tsDef)),
        tsResult.js.pipe(gulp.dest(paths.tsOutput))
    ]);
});

gulp.task('watch', ['ts-compile'], function () {
    gulp.watch(paths.tsSource, ['ts-compile']);
});

This will create a ts-compile and a watch task for us. Trying to run the compile task from VS Code (F1 – BackSpace – task ts-compile) will result in the following:
Running gulp --tasks-simple didn't list any tasks. Did you run npm install?
Run a Gulp task from Visual Studio Code vscode aurelia
So from the command window, in the root of the project, type:
npm install
After the installation of the packages are done, test the compile task again, either by staying in the command prompt and typing gulp ts-compile or by heading back to VS Code and running the task from there. If everything was installed and setup correctly the TypeScript compile will finish a compilation and report no errors.

Converting our app to an Aurelia app

Now we need to edit our index.html file again, and load Aurelia! πŸ™‚
Edit index.html and add a new script block under the other scripts that looks like this:

<script>
	System.import("aurelia-bootstrapper");
</script>

By default, Aurelia will look for a file named app.js to start up from, so let’s make sure we have one!
Add a folder in the root, name it AureliaLogic. Now add a TypeScript file in the AureliaLogic folder, name it app.ts and edit it like this:

import { AppRouter } from 'aurelia-router';

export class App {
	message: string;

	constructor(router: any) {
		this.message = "Hello from me!";
	}
}

The app.js file needs a template to work with as well, add a file named app.html in the wwwroot folder:

<template>
	<h1>Our first data-bound message</h1>
	<div>${message}</div>
</template>

Now we need to compile our typescript to emit the app.js file that Aurelia will look for. Do that using the Gulp ts-compile task we set up earlier.
However, the result will be a compilation error:
AureliaLogic\app.ts(1,27): error TS2307: Cannot find module 'aurelia-router'.
One more thing to fix πŸ™‚

Setting up type definitions for TypeScript

The reason that the TypeScript compiler fails is that it can’t find the aurelia-router type. So let’s help the compiler along the way!
Aurelia has type definitions delivered with the code, we just need to be able to get to them in an easy way. There are many ways to solve this but my proposal is the folowing:

  1. Install TSD – TSD is a package manager for TypeScript type files
  2. Copy Aurelia’s type definition files by hand or create a Gulp task to copy definition files from the Aurelia module folders
  3. Enable TSD to find all Aurelia definitions copied to the typings folder and bundle them

The above setup will enable us to only reference one single definition file form our TypeScript code files, and still be able to have all references available for all added Aurelia modules.

Install TSD

TSD is easily installed with npm, so just head over to the command prompt again, position in the root of the project and type:
npm install tsd
After installation we need to configure and setup tsd by typing:
tsd init
This will create a folder in the root of the project called typings, here we will put all our typing files (*.d.ts).

Create a Gulp task to copy d.ts files

We need another npm module here, so in package.json we need to add a reference to flatten under devDependencies:
"gulp-flatten": "^0.2.0"
Then add a copy task to to the gulpfile:

var gulp = require('gulp'),
    ts = require('gulp-typescript'),
    merge = require('merge'),
    flatten = require('gulp-flatten');

var webroot = "wwwroot";

var paths = {
    tsSource: './AureliaLogic/**/*.ts',
    tsOutput: "./" + webroot,
    tsDef: "./typings/",
    importedTypings: "./" + webroot + "/jspm_packages/**/*.d.ts"
};

Then define a new task at the bottom of the gulpfile:

gulp.task('copy-defs', function () {
    gulp.src(paths.importedTypings)
        .pipe(flatten())
        .pipe(gulp.dest(paths.tsDef + "/jspmImports/"));
});

Now install the new npm package by running:
npm install
And then run the copy script. If you don’t want to run the Gulp tasks from VS Code, it’s possible to run them from the console as well. Just position in the root of the project and type:
gulp copy-defs
This then executes the new copy task.
The last thing to fix regarding typing is to manually install the type definitions for core-js, do this by typing:
tsd install core-js

Now we need to get all our newly copied type definitions into our tsd file. Console to the resque as usual and type:
tsd rebundle
If all has gone well a load of d.ts files will be added form our new jspmImports folder and the type def for core-js will be there as well.

Add type references to our TypeScript file

Now we can add a reference to the tsd file in our app.ts file, add the following at the top of the file

/// <reference path="../typings/tsd.d.ts" />

Now run the TypeScript compile task again!
End result after setting up Aurelia with TypeScript using VS Code and ASP.NET 5 vscode
Given that everything has worked through the previous steps it’s now time to test the result in the browser by starting the ASP.NET 5 web server again if it’s off by running:
dnx web
Then open a browser and locate localhost:5000/index.html.
At first we will be seeing a classical Hello World, this will later be replaced by another message, as soon as Aurelia loads and takes over execution. Success!

About choosing no transpiler

So why not choosing a transpiler in the initial jspm setup?
Mostly because when starting out it’s nice to have more control with running the TypeScript compilation with Gulp. And since Gulp was used for a few other tasks it’s neat to use. One thing I never demoed in the post was the use of the watch-task. This is a great task when everything is setup correctly, as it will monitor your TypeScript files and compile them as soon as a change is saved in them, makes for a great quick feedback loop!

When choosing to setup TypeScript as compiler form jspm, it’s not necessary to compile the TypeScript files at all. This will be handled by a very cool plugin that will compile the TypeScript in the browser, but this also means you have to reload and watch the console for any compilation errors when working with it.

Version Disclaimer

At the time of writing this blog post, the following versions of tools and frameworks were used:
Visual Studio Code v0.10.2
TypeScript v1.6.2
Aurelia 1.0.0-beta.1
tsd v4
Gulp v3.9.0
Gulp-typescript v2.9.2
Merge v1.2.0
jspm v0.16.15
node v0.12.2
dnvm vrc-1

The code was tested in Microsoft Edge.

More TypeScript posts for the curious

Tutorial on TypeScript Functions: TypeScript Functions

Tutorial on TypeScript Classes: TypeScript Classes

Tutorial for setting up a TypeScript – ASP.NET 5 app in VS2015: Getting started: TypeScript 1.5 in Visual Studio 2015

Tutorial for setting up a TypeScript – ASP.NET 5 app in Visual Studio Code: How-to: TypeScript in Visual Studio Code

Setup of a TypeScript – MVC 6 app that uses RequireJS in VS2015: Setting up a TypeScript – RequireJS – Gulp – MVC 6 Web Project in Visual Studio 2015 RC

Happy coding! πŸ™‚

Aurelia, Visual Studio Code and TypeScript
Tagged on:                             

14 thoughts on “Aurelia, Visual Studio Code and TypeScript

  • November 30, 2015 at 14:55
    Permalink

    Hey Andreas!
    Great post, really enjoyed it. I’ve found a small mistake. In the section “Setting up TypeScript compilation with Gulp” you mentioned the project.json instead of the package.json file (“First we need to install a couple of npm packages. Open the project.json file in the root [..]) to install the required npm packages. Also in the code listing title (“project.json with added devDependencies section”).

    Reply
    • November 30, 2015 at 15:21
      Permalink

      Ouch! Thanks for the heads up, not good to edit the wrong .json πŸ™‚

      Thanks for reading it!

      Reply
      • November 30, 2015 at 15:29
        Permalink

        You’re welcome! πŸ™‚

        Reply
  • Pingback: TypeScript Classes Part II | mobilemancer

  • Pingback: TypeScript Classes Part III | mobilemancer

  • Pingback: Getting started: TypeScript 1.5 in Visual Studio 2015 | mobilemancer

  • December 15, 2015 at 01:51
    Permalink

    I’m impressed, I must say. Actually rarely do I experience a blog that’s equally educative and interesting, and I would like to inform you,
    you’ve struck the nail on the head.

    Reply
    • December 17, 2015 at 21:29
      Permalink

      Thanks πŸ™‚

      Reply
  • February 11, 2016 at 03:04
    Permalink

    I am curious why would one use Aurelia with Asp.NET MVC ? Is that purely for SEO ? I noticed the Skeleton app uses Razor Syntax for MVC views. Why would we want to use both ?

    Reply
    • February 16, 2016 at 22:00
      Permalink

      Hi,

      You don’t have to use ASP.Net/MVC with Aurelia. The Aurelia views are html intertwined with Aurelias binding syntax, no Razor involved πŸ™‚
      So it might be similar to the Razor syntax at times, but it’s actually not.

      Nor is there a need to host Aurelia from ASP.Net, in fact I’d bet most are not. I’m using it because I like MS tech, I work with MS tech professionally and like to play around with the new stuff on my spare time.

      Happy coding πŸ™‚

      Reply
  • March 11, 2016 at 15:24
    Permalink

    If I follow this post to the letter, I keep getting ‘Duplicate identifier ‘$1” errors. Any chance you know why this happens?

    Reply
  • March 11, 2016 at 16:46
    Permalink

    Actually – scratch that – I had copied in files from another project, and that caused issues

    Reply
    • March 13, 2016 at 22:35
      Permalink

      It’s not always easy when the error reporting is not crystal clear πŸ™‚

      Glad you got it working though. Hope you’re going to enjoy Aurelia as much as I am.

      Happy coding!

      Reply
  • Pingback: TypeScript Classes – mobilemancer

Leave a Reply

Your email address will not be published. Required fields are marked *