MVC5 and Angular 2.0

I started a small project to try and learn Angular 2.0, I didn’t however want to use ASP.NET 5.0 ( now Core 1.0 ) because I (rightfully so) knew the tooling wasn’t going to stick around dnx is now dotnet etc. I found that getting NG2 with typescript up and running wasn’t so simple. It required me to modify my csproj files and enable some of the lesser known things about type script:

For reference I’m using TypeScript 1.7.3 and these are the settings I use in the csproj

 <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets" Condition="false" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
  <TypeScriptTarget>ES5</TypeScriptTarget>
  <TypeScriptJSXEmit>None</TypeScriptJSXEmit>
  <TypeScriptCompileOnSaveEnabled>False</TypeScriptCompileOnSaveEnabled>
  <TypeScriptNoImplicitAny>False</TypeScriptNoImplicitAny>
  <TypeScriptModuleKind>System</TypeScriptModuleKind>
  <TypeScriptExperimentalDecorators>True</TypeScriptExperimentalDecorators>
  <TypeScriptModuleResolution>NodeJs</TypeScriptModuleResolution>
  <TypeScriptRemoveComments>True</TypeScriptRemoveComments>
  <TypeScriptOutFile />
  <TypeScriptOutDir />
  <TypeScriptGeneratesDeclarations>False</TypeScriptGeneratesDeclarations>
  <TypeScriptNoEmitOnError>True</TypeScriptNoEmitOnError>
  <TypeScriptSourceMap>True</TypeScriptSourceMap>
  <TypeScriptMapRoot />
  <TypeScriptSourceRoot />
</PropertyGroup>

This gets the editor to work with modules. Notice that ModuleResolution is NodeJs, this is not an error. This kindof confused me since any project that uses a tsconfig.json looks like this:

{
    "compilerOptions": {
        "noImplicitAny": false,
        "module": "system",
        "moduleResolution": "node",
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true,
        "noEmitOnError": false,
        "removeComments": false,
        "sourceMap": true,
        "target": "es5"
    },
  "exclude": [
    "node_modules"
  ]
}

the bit that threw me off was that in this file resolution is node. If you do this in the csproj it will not work.

You’ll also notice that the condition in the import is set to false. This too is intentional. This disables visual studio from compiling typescript.

Since I do use Visual Studio 2015 I have the Task Manager Console available to me. With this I do indeed use gulp for all of my TypeScript compilation. I do this for a couple of reasons. This does lead to another fact, The above tsconfig.json file is the one I currently use in this project.

  1. I can use VS Code if I want to and my files still get compiled without needing to go back into visual studio and click build since gulp has watches that you can add.
  2. Attempting to get Visual Studio ( with the MVC5 template ) to compile this code just flat would not work for me.

Since were on the topic I’ll go ahead and post my gulp file while were at it

var gulp = require('gulp'),
    ts = require('gulp-typescript'),
    merge = require('merge'),
    fs = require('fs'),
    del = require('del'),
    path = require('path')
    concat = require('gulp-concat'),
    sass = require('gulp-sass')
;
  
  
  
  
var lib = '/lib/';
  
var paths = {
    npm: './node_modules/',
    tsSource: './app/**/*.ts',
    tsOutput: lib + 'spa/',
    tsDef: lib + 'definitions/',
    jsVendors: lib + 'js',
    jsRxJSVendors: lib + 'js/rxjs',
    cssVendors: lib + 'css',
    imgVendors: lib + 'img',
    fontsVendors: lib + 'fonts'
};
  
  
var tsProject = ts.createProject('./tsconfig.json');
  
gulp.task('setup-vendors', function (done) {
    gulp.src([
      'node_modules/angular2/bundles/js',
      'node_modules/angular2/bundles/angular2.*.js*',
      'node_modules/angular2/bundles/http.*.js*',
      'node_modules/angular2/bundles/router.*.js*',
      'node_modules/es6-shim/es6-shim.js*',
      'node_modules/angular2/bundles/angular2-polyfills.js',
      'node_modules/rxjs/bundles/Rx.js',
      'node_modules/angular2/bundles/angular2.dev.js',
      'node_modules/zone.js/dist/zone.js',
      'bower_components/system.js/dist/*.*',
      'bower_components/system.js/dist/system.src.js',
      'bower_components/alertify.js/lib/alertify.min.js',
      'bower_components/tether/dist/js/tether.js',
      'bower_components/jquery/dist/jquery.js',
      'bower_components/material-design-lite/material.js'
    ]).pipe(gulp.dest(paths.jsVendors));
  
    gulp.src([
       'node_modules/rxjs/**/*.js'
    ]).pipe(gulp.dest(paths.jsRxJSVendors));
  
    gulp.src([
      'bower_components/material-design-lite/material.css'
    ]).pipe(gulp.dest(paths.cssVendors));
  
    gulp.src([
    ]).pipe(gulp.dest(paths.imgVendors));
  
    gulp.src([
    ]).pipe(gulp.dest(paths.fontsVendors));
  
    //gulp.src([
    //'node_modules/ng2-bootstrap/ng2-bootstrap.d.ts'
    //]).pipe(gulp.dest(paths.tsDef));
});
  
gulp.task('compile-typescript', function (done) {
    var tsResult = gulp.src([
       'node_modules/angular2/bundles/typings/angular2/angular2.d.ts',
       'node_modules/angular2/bundles/typings/angular2/http.d.ts',
       'node_modules/angular2/bundles/typings/angular2/router.d.ts',
       'app/**/*.ts'
    ])
     .pipe(ts(tsProject), undefined, ts.reporter.fullReporter());
    return tsResult.js
    .pipe(gulp.dest(paths.tsOutput));
});
  
gulp.task('compile-sass', function (done) {
    var tsResult = gulp.src([
       './app/sass/custom/**/*.scss';
    ])
   .pipe(sass().on('error', sass.logError))
  
        return tsResult.pipe(concat('app.css'))
   .pipe(gulp.dest('./Content'));
});
  
  
gulp.task('watch', ['compile-typescript', 'compile-sass'], function () {
    gulp.watch('app/**/*.ts', ['compile-typescript']);
    gulp.watch('app/sass/**/*.scss', ['compile-sass']);
});
  
gulp.task('clean-lib', function () {
    return del([lib]);
});
  
gulp.task('build-spa', ['setup-vendors', 'compile-typescript','compile-sass']);

Don’t get me wrong. There is a ton going on here, but the basics are start the Watch Task and just write code.

Just incase you’re curious The following is my bower.json and package.json.

{
  "name": "myproject",
  "dependencies": {
    "system.js": "~0.19.15",
    "material-design-lite": "1.0.6"
  }
}

{
  "name": "myproject",
  "version": "1.0.0",
  "devDependencies": {
    "angular2": "^2.0.0-beta.2", 
    "del": "2.2.0",
    "es6-promise": "^3.0.2",
    "es6-shim": "^0.33.13",
    "fs": "0.0.2",
    "gulp": "3.9.0",
    "gulp-concat": "2.6.0",
    "gulp-typescript": "2.10.0",
    "merge": "1.2.0",
    "path": "0.12.7",
    "reflect-metadata": "^0.1.2",
    "rxjs": "^5.0.0-beta.0",
    "ts": "0.0.0",
    "typescript": "1.7.5",
    "zone.js": "^0.5.10",
    "gulp-sass": "2.1.1" 
  }
} 

Leave a comment