Gulp Your TypeScript in ASP.NET 5

![gulp image](/content/images/2014/12/gulp.png)

If you have done any typescript development in Visual Studio in previous versions, you more than like are using the Web Essentials add in to perform the compilation to Javascript. Another option is to add a gulp task now that we have gulp and grunt support within Visual Studio. The other value add is if you are a non Visual Studio user this solution works just the same.

Project Creation

In Visual Studio 2015, File > New Project > ASP.NET Web Application > ASP.NET 5 Empty

or using the ASP.NET Yeoman Generator

$ yo aspnet 

     _-----_
    |       |    .--------------------------.
    |--(o)--|    |      Welcome to the      |
   `---------´   |   marvellous ASP.NET 5   |
    ( _´U`_ )    |        generator!        |
    /___A___\    '--------------------------'
     |  ~  |     
   __'.___.'__   
 ´   `  |° ´ Y ` 

? What type of application do you want to create? MVC Application
? What's the name of your ASP.NET application? (MvcApplication) GulpTypeScript

Adding Gulp

Add a package.json file.

or using the ASP.NET Yeoman Generator

$ yo aspnet:PackageJSON

Within package.json you will need to add the dependencies to support gulp.

  • gulp: Core gulp.js package
  • gulp-tsc: TypeScript compliler for gulp
  • gulp-shell: command line interface, can execute other processes etc.
  • run-sequence: run a series of tasks
{
    "version": "0.0.1",
    "name": "GulpTypeScript",
    "devDependencies": {
    	"gulp": "^3.8.5", 
    	"gulp-tsc": "^0.9.1", 
    	"gulp-shell": "^0.2.5",
    	"run-sequence":"^0.3.6"
    }
}

Unlike nuget (project.json > dependencies node), the npm packages are not automatically restored/downloaded once the package.json is saved. You can either expand the "Dependencies" node in the Solution Explorer and click "Restore Packages" or from a command line type npm install.

after npm install completes...

Adding the gulpfile.js

Using Visual Studio, Add New Item > JavaScript File > "gulpfile.js" or again using the aspnet Yeoman generator:

$ yo aspnet:JScript gruntfile

Adding the tasks

In this example, we'll put in a few simple tasks

  • build
  • clean
  • default
  • rebuild

the most important item being the build task as this is where the TypeScript compilation happens.

First declare the vars and dependencies...

    var gulp = require('gulp'),
        tsc = require('gulp-tsc'),
        shell = require('gulp-shell'),
        seq = require('run-sequence'),
        del = require('del');

Next, set the source (src) and destination (dest) paths for your scripts...

   var paths = {
        ts: {
            src: [
                'scripts/ts/*.ts'
            ],
            dest : 'scripts'
        }
    }

Here, set the "default" task to be run

   // Default
    gulp.task('default', ['build']);

A clean task is defined to delete any javascript files that were compiled to the destination location.

  // Clean
    gulp.task('clean', function (cb) {
        del(paths.ts.dest + '/*.js', cb);
    })

Next, a rebuild task is defined to execute the clean then build sequetiallly. You can use gulp.start('clean', 'build') but there is no guarantee what order the tasks will execute or complete in. So in that case the run-sequence npm package is used here.

    // ReBuild - Clean & Build
    gulp.task('rebuild', function (cb) {
        seq('clean', 'build', cb);
    });

Finally, the build task. Here the TypeScript compiler is leveraged using the gulp-tsc npm package passing in the arguments from the source location and producing the compiled JavaScript to the destination.

    // Build
    gulp.task('build', function () {
        return gulp
            .src(paths.ts.src)
            .pipe(tsc({
                module: "CommonJS",
                sourcemap: true,
                emitError: false
            }))
            .pipe(gulp.dest(paths.ts.dest));
    });
         

For demo purposes, just grabbed the "Simple Inheritance" example from TypeScriptLang.org and created "animal.ts" in the /scripts/ts folder.

class Animal {
    constructor(public name: string) { }
    move(meters: number) {
        alert(this.name + " moved " + meters + "m.");
    }
}

class Snake extends Animal {
    constructor(name: string) { super(name); }
    move() {
        alert("Slithering...");
        super.move(5);
    }
}

class Horse extends Animal {
    constructor(name: string) { super(name); }
    move() {
        alert("Galloping...");
        super.move(45);
    }
}

var sam = new Snake("Sammy the Python");
var tom: Animal = new Horse("Tommy the Palomino");

sam.move();
tom.move(34);

Now in order to produce the JavaScript, there are a few options as mentioned before.

  • Use Web Essentials
  • Open the command line, now that we have defined the gulp tasks, and type gulp [task name]
  • Task Runner Explorer

Command Line

Pretty simple here, as mdentioned above, open your console in your working directoy

$ gulp build

Output will be similar to (Windows)

C:\Github\GulpTypeScript\src\GulpTypeScript>gulp build
[16:58:08] Using gulpfile C:\Github\GulpTypeScript\src\GulpTypeScript\gulpfile.js
[16:58:08] Starting 'build'...
[16:58:08] Compiling TypeScript files using tsc version null
[16:58:09] Finished 'build' after 1.01 s

on OSX

$ gulp build
[17:00:43] Using gulpfile ~/GulpTypeScript/gulpfile.js
[17:00:43] Starting 'build'...
[17:00:43] Compiling TypeScript files using tsc version null
[17:00:43] Finished 'build' after 848 ms

The output goes right to /scripts as expected.

Bonus Task

Edit 01.05.2015 - Someone asked me was there a way to watch for file changes to recompile. Here is the task to add using the .watch() functionality of grunt.

    gulp.task('watch', function () {
        gulp.watch(paths.ts.src, ['build']);
    });

This task watches for file changes in the src directory, then executes the build task. You could optionally put in multiple tasks or call any existing task.

Task Runner Explorer

In Visual Studio 2015, there is now Task Runner Explorer which gives you a visual look into your tasks. This supports grunt and gulp. Here is a shot of the window after running the build task.

Note

On Windows you may encounter a strange error when executing the tasks. This is an issue when you have multiple versions of TypeScript installed.

The error: Failed to compile TypeScript: Error: Command failed: Cannot initialize ActiveScript

There is an easy fix, just go to to C:\Program Files(x86)\Microsoft SDKs\TypeScript
and remove the previous versions.

Summary

There is a lot more you can add to the grunt file as you may or may not know, there are minification, image optimization and a ton more. I like the way of gulp as it allows for the non VS and Visual Studio developers to put together the code in the same manner. Not to toss out Web Essentials, cause that is an awesome add-in and there would be many of features not in VS without it.