This repository aims to setup angular2 using the 5 Min QuickStart Guide using ASP.NET 5 in Visual Studio 2015.
If your interested in how this is done using the angular cli checkout Angular 2 (rc1) 5 Min QuickStart with Angular Cli and ASP.NET 5 in Visual Studio 2015. Spoiler Alert: it's a lot simpler!
The material2 branch is exactly the same except that it also uses Angular Material 2.
I'm using:
* Visual Studio 2015 Community Update 2
* ASP.NET and Web Tools 2015 (RC1 Update 1)
* Typescript 1.8.30.0
* Typings 0.8.1
* NPM 3.8.8
* Gulp 3.9.1
Visual Studio 2015 includes its own version of external tools, unfortunately these tools have not been updated causing errors with some required packages. To fix this we are going to force Visual Studio to use our global installs of node and npm. Follow the instructions in the follow blog - Customize external web tools in visual studio 2015.
-
Follow instructions to Install ASP.NET 5 on Windows
-
Upgrade to latest framework, in command prompt
> dnvm upgrade latest -r clr -arch x64
Have a look at the 5 Min QuickStart Guide before continuing to have a better understanding of we are doing here.
-
Open Visual Studio 2015 and click New Project... on Start Page.
-
Create an App folder in the root of the project
-
Add a TypeScript JSON Configuration File in the newly created App folder. This will add a file called tsconfig.json
-
Copy/paste the following into tsconfig.json
{ "compilerOptions": { "target": "es5", "module": "system", "moduleResolution": "node", "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "removeComments": false, "noImplicitAny": false, "outDir": "../wwwroot/app" }, "compileOnSave": true, "files": [ "../typings/main.d.ts" ] }
-
Add a JSON File called typings.json to the root folder and copy/paste the following:
{ "ambientDependencies": { "es6-shim": "registry:dt/es6-shim#0.31.2+20160317120654", "jasmine": "registry:dt/jasmine#2.2.0+20160412134438" } }
-
Add a NPM Configuration File in the root project file and copy/paste the following:
{ "name": "angular2-quickstart", "version": "1.0.0", "scripts": { "start": "tsc && concurrently \"npm run tsc:w\" \"npm run lite\" ", "lite": "lite-server", "postinstall": "typings install", "tsc": "tsc", "tsc:w": "tsc -w", "typings": "typings" }, "license": "ISC", "dependencies": { "@angular/common": "2.0.0-rc.0", "@angular/compiler": "2.0.0-rc.0", "@angular/core": "2.0.0-rc.0", "@angular/http": "2.0.0-rc.0", "@angular/platform-browser": "2.0.0-rc.0", "@angular/platform-browser-dynamic": "2.0.0-rc.0", "@angular/router-deprecated": "2.0.0-rc.0", "@angular/upgrade": "2.0.0-rc.0", "systemjs": "0.19.27", "es6-shim": "^0.35.0", "reflect-metadata": "^0.1.3", "rxjs": "5.0.0-beta.6", "zone.js": "^0.6.12", "angular2-in-memory-web-api": "0.0.5", "bootstrap": "^3.3.6" }, "devDependencies": { "concurrently": "^2.0.0", "lite-server": "^2.2.0", "typescript": "^1.8.10", "typings":"^0.8.1", "gulp": "^3.9.1", "del": "^2.2.0", "gulp-dest": "^0.2.3" } }
Right after saving this, ASP.NET 5 starts restoring the packages. It will download all packages mentioned in dependencies section of above package.json.
When all the packages are downloaded they are placed in the node_modules folder in the root. However in ASP.NET 5, wwwroot is our public web folder that means any static files outside of it wont be servered. We'll use GULP to copy them to wwwroot/libs.
-
Add a GULP Configuration File in the root project file and copy/paste the following:
/// <binding AfterBuild='moveToLibs, moveToApp' Clean='clean' /> var gulp = require('gulp'); var del = require('del'); var dest = require('gulp-dest'); var paths = { app: ['app/**/*.ts'], libs: [ 'node_modules/es6-shim/es6-shim.min.js', 'node_modules/es6-shim/es6-shim.map', 'node_modules/zone.js/dist/zone.js*', 'node_modules/reflect-metadata/Reflect.js*', 'node_modules/systemjs/dist/system.src.js*' ], packages: [ '@angular/common', '@angular/compiler', '@angular/core', '@angular/http', '@angular/platform-browser', '@angular/platform-browser-dynamic', '@angular/router', '@angular/testing', '@angular/upgrade' ], css: [ 'node_modules/bootstrap/dist/css/bootstrap.css', 'styles/styles.css' ] }; gulp.task('moveToLibs', function () { gulp.src(paths.libs).pipe(gulp.dest('./wwwroot/libs/js')); gulp.src(paths.css).pipe(gulp.dest('./wwwroot/libs/css')); gulp.src('node_modules/rxjs/**/*.js*').pipe(gulp.dest('./wwwroot/libs/js/rxjs')); for (var i = 0; i < paths.packages.length; i++) { gulp.src('node_modules/' + paths.packages[i] + '/*.js*').pipe(gulp.dest('./wwwroot/libs/js/' + paths.packages[i])); gulp.src('node_modules/' + paths.packages[i] + '/src/**/*.js*').pipe(gulp.dest('./wwwroot/libs/js/' + paths.packages[i] + '/src/')); } }); gulp.task('moveToApp', function () { gulp.src(paths.app).pipe(gulp.dest('wwwroot/app')); }); // clean all the generated typescript files gulp.task('clean', function () { return del(['wwwroot/app/**/*', 'wwwroot/libs/**/*']); });
-
Add a TypeScript File named app.component.ts to our App folder and paste the following lines:
import {Component} from '@angular/core'; @Component({ selector: 'my-app', template: '<h1>My First Angular 2 App</h1>' }) export class AppComponent { }
-
Update files property in tsconfig.json to look like
{ ... "files": [ "./app.component.ts", "../typings/main.d.ts" ] }
-
Add a TypeScript File named main.ts to our App folder and paste the following lines:
import {bootstrap} from '@angular/platform-browser-dynamic'; import {AppComponent} from './app.component'; bootstrap(AppComponent);
-
Update files property in tsconfig.json to look like
{ ... "files": [ "./app.component.ts", "./main.ts", "../typings/main.d.ts" ] }
-
Add a HTML Page named index.html to our wwwroot folder and paste the following lines:
<html> <head> <title>Angular 2 QuickStart</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="libs/css/styles.css"> <!-- 1. Load libraries --> <!-- Polyfill(s) for older browsers --> <script src="libs/js/es6-shim.min.js"></script> <script src="libs/js/zone.js"></script> <script src="libs/js/Reflect.js"></script> <script src="libs/js/system.src.js"></script> <!-- 2. Configure SystemJS --> <script src="systemjs.config.js"></script> <script> System.import('app').catch(function (err) { console.error(err); }); </script> </head> <!-- 3. Display the application --> <body> <my-app>Loading...</my-app> </body> </html>
-
Add support in ASP.NET 5 for static files.
-
Update project.json in the root folder, copy/paste the following:
{ "version": "1.0.0-*", "compilationOptions": { "emitEntryPoint": true }, "dependencies": { "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final", "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final", "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final" }, "commands": { "web": "Microsoft.AspNet.Server.Kestrel" }, "frameworks": { "dnx46": { }, "dnxcore50": { } }, "exclude": [ "wwwroot", "node_modules" ], "publishExclude": [ "**.user", "**.vspscc" ] }
-
Update Configure() in Startup.cs in the root folder
public void Configure(IApplicationBuilder app) { app.UseIISPlatformHandler(); app.UseDefaultFiles(); app.UseStaticFiles(); }
-
-
Add a JavScript File named systemjs.config.js to the wwwroot folder and paste the following lines:
(function(global) { // map tells the System loader where to look for things var map = { 'app': 'app', // 'dist', 'rxjs': 'libs/js/rxjs', 'angular2-in-memory-web-api': 'libs/js/angular2-in-memory-web-api', '@angular': 'libs/js/@angular' }; // packages tells the System loader how to load when no filename and/or no extension var packages = { 'app': { main: 'main.js', defaultExtension: 'js' }, 'rxjs': { defaultExtension: 'js' }, 'angular2-in-memory-web-api': { defaultExtension: 'js' } }; var packageNames = [ 'libs/js/@angular/common', 'libs/js/@angular/compiler', 'libs/js/@angular/core', 'libs/js/@angular/http', 'libs/js/@angular/platform-browser', 'libs/js/@angular/platform-browser-dynamic', 'libs/js/@angular/router', 'libs/js/@angular/testing', 'libs/js/@angular/upgrade' ]; // add package entries for angular packages in the form '@angular/common': { main: 'index.js', defaultExtension: 'js' } packageNames.forEach(function(pkgName) { packages[pkgName] = { main: 'index.js', defaultExtension: 'js' }; }); var config = { map: map, packages: packages } // filterSystemConfig - index.html's chance to modify config before we register it. if (global.filterSystemConfig) { global.filterSystemConfig(config); } System.config(config); })(this);
-
Create a *styles folder in the root project folder
-
Add a Style Sheet named styles.css to the styles folder and paste the following lines:
/* Master Styles */ h1 { color: #369; font-family: Arial, Helvetica, sans-serif; font-size: 250%; } h2, h3 { color: #444; font-family: Arial, Helvetica, sans-serif; font-weight: lighter; } body { margin: 2em; } body, input[text], button { color: #888; font-family: Cambria, Georgia; } /* * See https://github.com/angular/angular.io/blob/master/public/docs/_examples/styles.css * for the full set of master styles used by the documentation samples */
- Press F5 in Visual Studio, a browser tab should open with My First Angular 2 App displayed
So far we have a pretty static solution and are not taking advantage of ASP.NET 5 so lets make some changes.
-
Update dependencies property in project.json, copy/paste the following:
"dependencies": { "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final", "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final", "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final", "Microsoft.AspNet.Mvc": "6.0.0-rc1-final", "Microsoft.Extensions.Configuration.FileProviderExtensions": "1.0.0-rc1-final", "Microsoft.Extensions.Configuration.Json": "1.0.0-rc1-final", "Microsoft.Extensions.Logging": "1.0.0-rc1-final", "Microsoft.Extensions.Logging.Console": "1.0.0-rc1-final", "Microsoft.Extensions.Logging.Debug": "1.0.0-rc1-final", "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final", "Microsoft.AspNet.Tooling.Razor": "1.0.0-rc1-final", "Microsoft.Extensions.CodeGenerators.Mvc": "1.0.0-rc1-final" }
-
Add a Controllers folder in the root project folder
-
Add a MVC Controller Class called HomeController in controllers folder
-
Add a Views folder in the root project folder
-
Add a MVC View Start Page called _ViewStart.cshtml in views folder
-
Add a MVC View Imports Page called _ViewImports.cshtml in views folder
-
Update Views/_ViewImports.cshtml, copy/paste the following:
@using WebApp @addTagHelper "*, Microsoft.AspNet.Mvc.TagHelpers"
-
Add a Shared folder to the views folder
-
Add a MVC View Layout Page called _Layout.cshtml to views/shared folder
-
Add a Home folder to the views folder
-
Add a MVC View Page called Index.cshtml to the views/home folder
-
Add a config folder to the root project folder
-
Add a ASP.NET Configuration File called appsettings.json to the config folder
-
Replace appsettings.json, copy/paste the following:
{ "Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Verbose", "System": "Information", "Microsoft": "Information" } } }
-
Replace Startup.cs, copy/paste the following:
using Microsoft.AspNet.Builder; using Microsoft.AspNet.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace WebApp { public class Startup { public Startup( IHostingEnvironment env ) { // Set up configuration sources. var builder = new ConfigurationBuilder() .AddJsonFile("config/appsettings.json") .AddJsonFile($"config/appsettings.{env.EnvironmentName}.json", optional: true); builder.AddEnvironmentVariables(); Configuration = builder.Build() .ReloadOnChanged("config/appsettings.json") .ReloadOnChanged($"config/appsettings.{env.EnvironmentName}.json"); } public IConfigurationRoot Configuration { get; set; } // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddMvc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory ) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); app.UseIISPlatformHandler(); app.UseStaticFiles(); app.UseMvc(routes => { routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}"); routes.MapRoute("spa-fallback", "{*anything}", new { controller = "Home", action = "Index" }); }); } // Entry point for the application. public static void Main(string[] args) => WebApplication.Run<Startup>(args); } }
-
Replace _Layout.cshtml in Views/Shared folder. Copy/paste the following:
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width"/> <title>@ViewBag.Title</title> @RenderSection("Styles", required: false) @RenderSection("HeadScripts", required: false) </head> @await FlushAsync() <body> <div> @RenderBody() </div> </body> </html>
-
Replace Index.cshtml in Views/Home folder. Copy/paste the following:
@{ ViewBag.Title = "Angular 2 QuickStart"; } @section Styles { <link rel="stylesheet" href="libs/css/styles.css"> } @section HeadScripts { <!-- 1. Load libraries --> <!-- Polyfill(s) for older browsers --> <script src="libs/js/es6-shim.min.js"></script> <script src="libs/js/zone.js"></script> <script src="libs/js/Reflect.js"></script> <script src="libs/js/system.src.js"></script> <!-- 2. Configure SystemJS --> <script src="systemjs.config.js"></script> <script> System.import('app').catch(function (err) { console.error(err); }); </script> } <cache vary-by="@Context.Request.Path"> <my-app>Loading...</my-app> </cache>
-
Delete Index.html in wwwroot
The following resources were used to fill in the blanks