I am playing around with Angular2 in combination with ASP.NET5, gulp and typescript. Everything works fine when I solve the tutorials for Angular, but I am not sure how to setup the process in combination with ASP.NET 5.
I made a project with working typescript compilation and bundling and I now the issues are starting:
When I add the tsConfig file to the root of the project, visual studio does not recognizes the file. When I place it to wwwroot/scripts everything is fine (very strange).
Angular2 does not support DefinityTyped anymore, the file is empty and contains the hint that I must install the npm package. I did it but there are so many files. Which type definitions do I have to include? None of them work. I always get the error that it cannot find angular2/angular2.
It is very strange. When I use commonjs for typescript the compilation works. I am really confused because I dont understand how the include works. Resharper shows a lot of errors but when I can disable it for the moment.
The Angular2 NPM Package also contains the script files. But because of the fact that they are outside I cannot reference them directly. I cannot find a bower package with the scripts and it also make no sense to have the package twice.
I would be quite happy about a tutorial or some best practices how to setup angular2 with asp.net 5.
By the way: There are so many package managers: NPM, NuGet, gulp, tsd...
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 the wwwroot\lib
directory structure. This could be done as follows in gulpfile.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/lib
gulp.task('build-wwwroot-lib', function() {
return gulp
.src(config.lib, { base: nodeModulesPath })
.pipe(gulp.dest(wwwrootLibPath));
});