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.
- Package.json file does not exist, create it? [yes]:
- Would you like jspm to prefix the jspm package.json properties under jspm? [yes]:
- Enter server baseURL (public folder path) [./]:wwwroot
- Enter jspm packages folder [wwwroot\jspm_packages]:
- Enter config file path [wwwroot\config.js]:
- Configuration file wwwroot\config.js doesn’t exist, create it? [yes]:
- Enter client baseURL (public folder URL) [/]:
- 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?
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:
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:
- Install TSD – TSD is a package manager for TypeScript type files
- Copy Aurelia’s type definition files by hand or create a Gulp task to copy definition files from the Aurelia module folders
- 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!
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! π
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”).
Ouch! Thanks for the heads up, not good to edit the wrong .json π
Thanks for reading it!
You’re welcome! π
Pingback: TypeScript Classes Part II | mobilemancer
Pingback: TypeScript Classes Part III | mobilemancer
Pingback: Getting started: TypeScript 1.5 in Visual Studio 2015 | mobilemancer
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.
Thanks π
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 ?
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 π
If I follow this post to the letter, I keep getting ‘Duplicate identifier ‘$1” errors. Any chance you know why this happens?
Actually – scratch that – I had copied in files from another project, and that caused issues
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!
Pingback: TypeScript Classes – mobilemancer