Angular2 with ASP.NET 5 [closed]
I agree, it is somewhat bewildering at first to get Angular2 up and running in the Visual Studio Asp.net 5 environment. I put the typescript files associated with my Angular2 app in a folder on the root called App (capital "A") and then use gulp to transpile into javascript into the "app" (small "a") at "./wwwroot/app". The tsconfig.json file seems to function okay in the App folder and it looks like the following:
{ "compilerOptions": { "emitDecoratorMetadata": true, "experimentalDecorators": true, "module": "system", "moduleResolution": "node", "noImplicitAny": false, "noEmitOnError": true, "removeComments": false, "sourceMap": true, "target": "es5", "outDir": "wwwroot/app/" }, "exclude": [ "node_modules", "wwwroot" ]}
My gulp task looks like the following (note that I also need to copy any associated HTML views and JSON files to the app folder as well):
var ts = require("gulp-typescript")var tsProject = ts.createProject("./App/tsconfig.json");gulp.task("compile:ts", function () { var tsResult = tsProject.src() .pipe(ts(tsProject)); tsResult.js.pipe(gulp.dest("./wwwroot/app")); return gulp.src('./App/**/*.{html,json}') .pipe(gulp.dest('./wwwroot/app'));});
Now when I run the gulp task compile:ts my app folder gets all the proper assets.
Now, I realize you probably do not want to hear about yet another package manger, but I recommend you consider using JSPM. Built by the same team that built system.js, JSPM really excels in bundling your Angular2 app for production. JSPM requires that you have a config.json file in your root and mine (configured to tell JSPM where the angular2 dev dependencies are) is as follows:
System.config({ baseURL: "/", defaultJSExtensions: true, transpiler: "typescript", paths: { "npm:*": "jspm_packages/npm/*", "github:*": "jspm_packages/github/*", "node_modules*": "node_modules/*" }, packages: { "app": { "defaultExtension": "js" } }, map: { "angular2": "node_modules/angular2", "bootstrap": "github:twbs/bootstrap@3.3.6", "jquery": "github:components/jquery@2.1.4", "rxjs": "node_modules/rxjs", "ts": "github:frankwallis/plugin-typescript@2.4.3", "typescript": "npm:typescript@1.7.5", "github:frankwallis/plugin-typescript@2.4.3": { "typescript": "npm:typescript@1.7.5" }, "github:twbs/bootstrap@3.3.6": { "jquery": "github:components/jquery@2.1.4" } }});
The I use a gulp-jspm to execute the bundling into on self-contained js file:
var gulp_jspm = require("gulp-jspm");gulp.task("jspm_bundle", ["compile:ts"], function() { return gulp.src("./wwwroot/app/bootApp.js") .pipe(gulp_jspm({ selfExecutingBundle: true })) .pipe(gulp.dest("./wwwroot/app-build/"));});
Then into your index.html file you have one nice tidy script reference:
<script src="~/app-build/bootApp.bundle.min.js?v=@AppSettings.Value.BundleVersion"> </script>
When I build for production I change the BundleVersion variable as a cache buster.
In relation to point #4, I believe that there are no plans to produce a Bower package for angular2 (see https://github.com/angular/angular/issues/4018). This seems likely to cause some friction with Visual Studio 2015 ASP.NET 5 template projects which are set up to use Bower for client-side packages (see http://docs.asp.net/en/latest/client-side/bower.html).
I have worked around this as follows:
- Install the angular2 npm package:
npm install --save angular2
Configure a gulp task to copy relevant files from the
node_modules
directory structure to thewwwroot\lib
directory structure. This could be done as follows ingulpfile.js
:/// <binding BeforeBuild='build-wwwroot-lib' />var gulp = require('gulp');var nodeModulesPath = './node_modules';var wwwrootLibPath = './wwwroot/lib';var libFiles = [ nodeModulesPath + '/angular2/bundles/**', nodeModulesPath + '/es6-promise/dist/**', nodeModulesPath + '/es6-shim/es6-*', nodeModulesPath + '/reflect-metadata/Reflect*js', nodeModulesPath + '/rxjs/bundles/**', nodeModulesPath + '/zone.js/dist/**', /* ... Add other files required here as necessary ... */];// Install relevant assets from node_modules to wwwroot/libgulp.task('build-wwwroot-lib', function() { return gulp .src(config.lib, { base: nodeModulesPath }) .pipe(gulp.dest(wwwrootLibPath));});