Build 2017 Videos for Angular Developers

Build 2017 Videos for Angular Developers

After watching approximately six hours of keynote videos from Microsoft's Build Conference 2017, it's clear that no single company produces more software for developers than Microsoft. There are tools for virtually every platform. There are SDKs for Windows, Xbox, and Office. You can even use Visual Studio to develop an extension for Visual Studio.

With so many developer products, how do you determine which is relevant to you? That question is the inspiration for this post.

The following is a categorized list of videos from Build 2017 that are most relevant to an Angular web developer. The usual suspects are here including TypeScript, Visual Studio 2017, Visual Studio Code, Progressive Web Apps (PWA), ASP.NET, and Node.js. Going further are newer technologies such as Azure Serverless products, brand-new Cosmos DB, Mixed Reality, Artificial Intelligence offerings, and the debut of Fluent Design.

For the full list of all 450 videos, visit the event page on Channel9. Also if you find a favorite video absent from the list, please leave a comment.

Angular and Front-End

Tooling

Visual Studio Code

Visual Studio 2017

More Tooling

ASP.NET

Node.js

Azure – Serverless

Keynotes

Mixed Reality

Azure – Cosmos DB

Microsoft Graph

Fluent Design

Artificial Intelligence (AI)

Bot Framework

Cognitive Services

More AI

ASP.NET Core JavaScript Services with Webpack HMR

ASP.NET Core JavaScript Services with Webpack HMR Hero

Derived from photo by Alasdair / flickr.com, CC BY

This tutorial covers two aspects of the ASP.NET Core JavaScript Services library. First, MapSpaFallbackRoute, is a utility to help redirect client-side routes to the browser. Second is a utility for integrating webpack dev middleware as ASP.NET Core middleware. This provides webpack's hot module replacement (HMR) functionality integrated with the ASP.NET Core request pipeline. When this is enabled, the code in the browser automatically replaces the updated ES2015 module without a full application refresh. This is an incredibly productive development setup.

The tutorial uses Visual Studio Code as the editor. If you would like to go directly to the completed example, the code is on GitHub.

Initial Setup

  1. Follow the steps in this post to create an 'empty' Angular, ASP.NET Core project using the Angular and dotnet command line interfaces (CLI). The rest of the tutorial builds off this base project.
  2. Next, add the code for multiple components to the project's src/app directory. Upon completion, the files should be in this structure with the following contents:

    ├── src
    |   ├── app
    |   |   └── app.component.ts
    |   |   ├── app.module.ts
    |   |   ├── base.component.html
    |   |   ├── main.component.ts
    |   |   └── other.component.ts
    

    app.component.ts

    import { Component } from '@angular/core';
    
    // exported to use with webpack HMR
    export const rootElementTagName = 'app-root';
    
    @Component({
    selector: rootElementTagName,
    template: `
      <nav>
        <a routerLink="/main">main</a> |
        <a routerLink="/other">other</a>
      </nav>
      <router-outlet></router-outlet>
    `
    })
    export class AppComponent { }
    

    base.component.html

    <h1>
    {{title}}
    </h1>
    

    main.component.ts

    import { Component } from '@angular/core';
    
    @Component({
    selector: 'app-main',
    templateUrl: './base.component.html'
    })
    export class MainComponent {
    title = 'this is the main component';
    }
    

    other.component.ts

    import { Component } from '@angular/core';
    
    @Component({
    selector: 'app-other',
    templateUrl: './base.component.html'
    })
    export class OtherComponent {
    title = 'this is the other component';
    }
    
  3. Finally, configure components in the NgModule app.module.ts.

    app.module.ts

    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { FormsModule } from '@angular/forms';
    import { HttpModule } from '@angular/http';
    import { RouterModule, Routes } from '@angular/router';
    
    import { AppComponent, rootElementTagName } from './app.component';
    import { MainComponent } from './main.component';
    import { OtherComponent } from './other.component';
    
    const routes: Routes = [
    { path: '', redirectTo: '/main', pathMatch: 'full' },
    { path: 'main',  component: MainComponent },
    { path: 'other', component: OtherComponent },
    ];
    
    @NgModule({
    declarations: [
      AppComponent,
      MainComponent,
      OtherComponent
    ],
    imports: [
      BrowserModule,
      FormsModule,
      HttpModule,
      RouterModule.forRoot(routes)
    ],
    providers: [],
    bootstrap: [AppComponent]
    })
    export class AppModule { }
    
    export { rootElementTagName } from './app.component';
    

    Now run the application in Visual Studio Code using F5. The client-side routes are configured and you can switch between the main and other views.

Configure Server-Side Routing with MapSpaFallbackRoute

The ASP.NET Core JavaScript Services library includes a utility to configure single page application (SPA) routing. This enables the server to handle any requests intended for the Angular router by returning the Angular application to the browser. Once the browser loads the Angular application, Angular takes over the URL routing. For more information on how Angular and ASP.NET Core routes integrate, see this post.

These steps configure server-side routing.

  1. Within the project directory, use the command dotnet add package Microsoft.AspNetCore.SpaServices to add the ASP.NET Core JavaScript Services library to the project. Restore the new package when Visual Studio Code displays the prompt or by using the command dotnet restore.

  2. In the Startup.cs file add the ASP.NET MVC service as well as the MapSpaFallbackRoute:

    Startup.cs

    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.SpaServices.Webpack;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Logging;
    
    namespace my_directory
    {
    public class Startup
    {
      // 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 https://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();
    
        if (env.IsDevelopment())
        {
          app.UseDeveloperExceptionPage();
        }       
    
        app.UseDefaultFiles();
        app.UseStaticFiles();     
    
        app.UseMvc(routes => {
          routes.MapSpaFallbackRoute(
            name: "spa-fallback",
            defaults: new { controller = "Home", action = "Index" });
        });
      }
    }
    }
    

    Note: Ensure that the namespace my-directory is replaced with the namespace of your application.

  3. The MapSpaFallbackRoute points to a HomeController. Create a Controllers directory and add this controller as a pass-through to simply return the Angular application for routes that should be addressed on the client.

    HomeController.cs

    using Microsoft.AspNetCore.Mvc;
    
    public class HomeController : ControllerBase
    {
      public IActionResult Index()
      {
          var fileName = "index.html";
          var contentType = "text/html";
    
          return File(fileName, contentType);
      }
    }
    

Run the application with F5. Go directly to the URL http://localhost:5000/other in the browser's address bar (not by linking from within the application) and see that the Angular application successfully loads the route.

Configure Hot Module Replacement

One of the more compelling features of webpack is its ability to apply code updates in the browser while the application is running so you can quickly see the resulting changes. This is webpack's Hot Module Replacement (HMR) feature and the JavaScript Services library includes the ability to integrate with this functionality using ASP.NET Core middleware.

  1. Type ng eject in the terminal to have Angular CLI switch the configuration to a webpack-based configuration. At this point any configuration changes that you want to make to the build must be done through the webpack configuration. The Angular CLI configuration no longer applies.

  2. Run npm install aspnet-webpack webpack-hot-middleware -D to download required Node.js packages. Also, run npm install to ensure all the new webpack package dependencies are downloaded.

  3. Configure the webpack middleware in the Startup.cs file. Add the webpack dev middleware configuration within the env.IsDevelopment() conditaion. By default, Visual Studio Code configures ASP.NET Core to run in Development mode so this condition evaluates to true.

    Startup.cs

    // ...
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
    // ...
    if (env.IsDevelopment())
    {
      app.UseDeveloperExceptionPage();
      app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions {
        HotModuleReplacement = true
      });
    }
    
    app.UseDefaultFiles();
    
    // ...
    }
    
  4. When running the project with webpack HMR, you do not need to build with webpack as part of the .csproj build. Update this configuration to avoid the extra processing at compile time. By default, the build runs with a 'Debug' configuration which will not trigger the webpack build.

    my-directory.csproj

    <Target Name="AngularBuild" AfterTargets="Build">
    <Exec Condition="'$(Configuration)' == 'Release'" Command="npm run build" />
    </Target>
    

    Note: Attentive readers may notice that the tutorial uses ASP.NET Core configuration for enabling the webpack dev middleware and alternatively a build configuration constant for enabling the non-HMR build. This tutorial focuses on improving the developer experience with webpack HMR. There are many options for synchronizing these configurations to be explored in future posts.

  5. Set "publicPath" to "/" in the webpack.config.js file under the "output" section.

    "output": {
    "path": path.join(process.cwd(), "wwwroot"),
    "filename": "[name].bundle.js",
    "publicPath": "/",
    "chunkFilename": "[id].chunk.js"
    },
    
  6. Finally, you must handle the HMR changes in the browser to refresh the Angular application with updated modules. Add a TypeScript file to the src directory named handleHotModule.ts and use it to handle the HMR changes during the Angular bootstrap process in main.ts.

    handleHotModule.ts

    import { Type, PlatformRef } from '@angular/core';
    
    interface HotModule extends NodeModule {
    hot?: HotModuleHandler;
    }
    
    interface HotModuleHandler {
    accept: () => void;
    dispose: (callback: () => void) => void;
    }
    
    export function handleHotModule(
    bootstrapModule: HotModule,
    rootElemTagName: string,
    platform: PlatformRef,
    bootFunction: (isModuleHot: boolean) => void
    )  : void {
    const isModuleHot = !!bootstrapModule.hot; 
    
    if (isModuleHot) {
      bootstrapModule.hot.accept();
      bootstrapModule.hot.dispose(() => {
        const oldRootElem = document.querySelector(rootElemTagName);
        const newRootElem = document.createElement(rootElemTagName);
        oldRootElem.parentNode.insertBefore(newRootElem, oldRootElem);
        platform.destroy();
      });
    }
    
    if (document.readyState === 'complete') {
      bootFunction(isModuleHot);
    } else {
      document.addEventListener('DOMContentLoaded', () => {
        bootFunction(isModuleHot);
      });
    }
    }
    

    main.ts

    import { enableProdMode } from '@angular/core';
    import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
    
    import { AppModule, rootElementTagName } from './app/app.module';
    import { environment } from './environments/environment';
    import { handleHotModule } from './handleHotModule';
    
    const platform = platformBrowserDynamic();
    
    handleHotModule(module, rootElementTagName, platform, isModuleHot => {
    if (environment.production && !isModuleHot) {
      enableProdMode();
    }
    
    platform.bootstrapModule(AppModule);
    });
    

    Now run the application. After the application loads, make a change to one of the components and save the file. Upon saving, you see the update appear in the browser almost immediately after you press save in the editor.

Your New Developer Experience

Welcome to your new developer experience with ASP.NET Core and Angular powered by webpack and ASP.NET Core JavaScript Services. The ASP.NET Core JavaScript Services library has so much more including server-side pre-rendering with Angular Universal and lower level utilities to interface with Node.js code.

Take some time to look at the respository on GitHub. There are additional details included there for your reference.

Give this setup a try and drop a comment about your experience. What other build configurations and developer features do you want to see featured on the blog?

Get Going with the Angular and ASP.NET CLIs

Angular and ASP.NET CLIs Header

When learning Angular and ASP.NET Core, it's oftentimes helpful to start with an empty project. However, there are some integration steps required to have Angular and ASP.NET Core work together.

This tutorial shows how to create an Angular, ASP.NET Core project using the command line interfaces (CLI) for both Angular and .NET Core. It demonstrates how to host and debug an ASP.NET Core project in Visual Studio Code.

Prerequisites

The following must be installed to complete this tutorial:

Note: The commands in this article work on a Windows machine with PowerShell. Other platforms may require modifications.

Configure Angular

  1. Install Angular CLI globally to make the commands available in any directory

    npm install -g @angular/cli
    
  2. Use the newly installed Angular CLI to scaffold a new project. This command creates a new directory to house your application. It may take a couple minutes to complete because the utility installs the npm packages for Angular, the build, and testing.

    ng new my-directory
    
  3. Navigate into the repository and verify the application by running it with the Angular CLI. Use the --open argument to open the application in the default browser.

    cd my-directory
    ng serve --open
    

    The Angular CLI runs the application on a Node.js web server and you will see the stub page.

    Angular CLI Stub Page

  4. Terminate the running web server with the key combination Ctrl + C to continue in the command window.

Configure ASP.NET Core

  1. In the repository, use the .NET Core CLI to scaffold an empty ASP.NET Core project.

    dotnet new web
    

    Note: The dotnet new command scaffolds the .NET project within the current working directory whereas the Angular CLI command ng new creates a new directory to contain the generated Angular code.

  2. Install the ASP.NET static file support middleware.

    dotnet add package Microsoft.AspNetCore.StaticFiles
    
  3. Open the repository in Visual Studio Code

    code .
    
  4. Visual Studio Code prompts you to configure the application and to restore .NET packages. Press Yes and Restore respectively. The editor generates a .vscode folder containing configuration files and downloads the .NET Core dependencies.

    .NET Core Configuration Prompt

    Tip: If the prompt doesn't appear initially, open a C# file in the editor.

  5. Configure the Angular CLI to output the Angular build to the wwwroot folder. Open the .angular-cli.json configuration file and change "outDir": "dist" to "outDir": "wwwroot".

    {
    // ...
    "apps": [
     {
        "root": "src",
        "outDir": "wwwroot",
        // ...
    }
    }
    
  6. Configure static file support in the Startup.cs file. The Configure method should have the following code.

    public void Configure(IApplicationBuilder app,
      IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
      loggerFactory.AddConsole();
    
      if (env.IsDevelopment())
      {
          app.UseDeveloperExceptionPage();
      }
    
      app.UseDefaultFiles();
      app.UseStaticFiles();
    }
    
  7. Add a build step to the .csproj file to build the Angular application with the Angular CLI.

    <Target Name="AngularBuild" AfterTargets="Build">
      <Exec Command="npm run build" />
    </Target>
    
  8. Press the F5 key to run the ASP.NET application with Visual Studio Code's debugger. The Angular application is now hosted from ASP.NET Core instead of Node.js. Notice how ASP.NET Core uses port 5000 by default as opposed to 4200 with the Angular CLI.

    Angular CLI Stub Page on ASP.NET Core

    Completed Startup.cs Code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Http;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Logging;
    
    namespace my_directory
    {
      public class Startup
      {
          // 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  https://go.microsoft.com/fwlink/?LinkID=398940
          public void ConfigureServices(IServiceCollection services)
          {
          }
    
          // 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();
    
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
    
            app.UseDefaultFiles();
            app.UseStaticFiles();
        }
      }
    }
    

    Completed my-directory.csproj Code:

    <Project Sdk="Microsoft.NET.Sdk.Web">
    <PropertyGroup>
      <TargetFramework>netcoreapp1.1</TargetFramework>
    </PropertyGroup>
    
    <ItemGroup>
      <Folder Include="wwwroot\" />
    </ItemGroup>
    
    <ItemGroup>
      <PackageReference Include="Microsoft.AspNetCore" Version="1.1.1" />
      <PackageReference Include="Microsoft.AspNetCore.StaticFiles"  Version="1.1.1" />
    </ItemGroup>
    
    <Target Name="AngularBuild" AfterTargets="Build">
      <Exec Command="npm run build" />
    </Target>
    </Project>
    

Conclusion

The tooling has finally come together for both Angular and ASP.NET so that anyone can easily create an application using the command line.

Use the steps here to build the foundation and then move to integrate other features like routing and authentication. In fact, learn to integrate routing right here.

Have you been using the CLI for Angular or ASP.NET Core? What do you like or dislike about them? Please leave a note in the comments.

Angular and the Server

Angular and the Server Header

Derived from photo by jeanbaptisteparis / flickr.com, CC BY-SA

Coming from an ASP.NET background, developers are familiar with the File, New Project… experience. This is the process to setup a new project in Visual Studio – typically from a template to help you get started effectively.

These starter projects include everything in the box. They have UI rendering, authentication, sample data APIs, and more. And while they are great for getting started, they may not be the best design for the application you are building.

When it comes to building an Angular application, how should it integrate with the server-side application if at all? What design options are available to you and how do you know which is the right one? This is an often-overlooked topic in Angular-focused material. One the other end, server-side articles tend to encourage using server-side features without considering that you are using a very powerful front-end framework already.

This article details several application responsibilities and groups them in terms of their integration with the host application. For the purposes of this article, the host application is the server-side application that sits beneath your Angular application and serves it to the browser/client. (Spoiler alert, there might be NO application sitting beneath your Angular application.) The Angular application consists of the TypeScript and/or JavaScript you write against the Angular framework.

Level 0 – No Server Application

This level includes features that are configurable to have no server-side dependency. This means that when the application runs, Angular handles these features without requiring the server to process any of the logic. This configuration may be desirable especially when static file hosting is the preferred deployment option.

Even though there is no run-time server dependency, you can still leverage the power of a build to optimize your application. These are some of the features you can configure with no server-side backend.

Routing

The Angular router is optionally configured to use the hash URL style. In this configuration, each route is represented in the URL following the hash symbol, like example.com/#/about or example.com/#/products/1. The main benefit is that when someone enters this URL into the browser, they are going to the same endpoint each time, example.com. When the application loads, the router kicks in and navigates to the correct view.

Internationalization (i18n)

Angular includes utilities to internationalize applications. There are several phases to this process which you can read about in the documentation. At the end, you are left with multiple versions of your application that are deployed to their own directory as static files. At this point, there are several options for routing the user to the correct version of the application. The choice can be left to the user in the UI or the application can read the language settings in the browser to automatically route to the correct locale.

View Rendering

One of the first highlights of the Angular framework was its rendering. Being able to bind a JavaScript object to a template and see the data and events wire themselves up was almost magic. Angular accomplishes this in the browser and while server frameworks have their own rendering engines, you can generally rely on client-side rendering for your views when using Angular.

Level 1 – Host Application Integration

This level consists of functionality where the host application and the Angular application work together to produce the runtime functionality. While the server may not know intimately about the Angular application, both the server and client must be configured in a complimentary manner and make assumptions about the other's behavior.

Routing

As opposed to the hash style URL discussed earlier, the more common HTML 5 pushState style URL depends on server support. These URLs lack the hash symbol, for example example.com/about or example.com/products/1. The issue here is that when someone navigates to your application the first time using one of these URLs, the Angular application doesn't have a chance to handle the route. Instead, the server receives the request first and then returns the Angular application to the client to then complete the routing process. You can see an example with ASP.NET Core here.

Authentication

Sometimes, there are reasons to lock down your Angular application to only authorized users. While the Angular application could handle this based off of Web API authentication, you also have the option to authorize with the host application. For instance, the first time someone navigates to your web application, the server can return the 'not authorized' messaging without returning any of the Angular code to the browser.

View Rendering

As mentioned previously, Angular's rendering is more than capable of generating your application's UI. Generally, this rendering occurs in the browser. However, applications optimized for SEO and time-to-load performance, benefit from server-side rendering.

This is where Angular Universal fits in. Instead of using the server framework's view engine, Angular Universal renders Angular templates server-side. The browser receives the HTML and CSS to display the page immediately without client-side rendering. Subsequent views are loaded via AJAX and rendered on the client to reduce subsequent payload sizes. The framework supports both Node.js and ASP.NET Core backends.

Using Angular Universal does increase complexity and imposes certain restrictions in how you write your Angular application. Be sure that if you need this extra performance boost that you understand the trade-offs. Read more about it on GitHub.

Internationalization

Internationalization is an area where the host application may not have a direct role but may need to assist integrated routing, authentication, and/or rendering to provide the desired experience.

Logging

Logging also doesn't necessarily represent a tight integration between the host application and the Angular application. However, consider that as you increase the server's role with routing, authentication, and/or rendering, you should consider logging any errors resulting from this increased responsibility.

Level 2 – Web APIs

These dependencies are server-side dependencies. However, they do not have to live within the same web application hosting the Angular application. By keeping these dependencies in their own code base, there are many advantages. Builds and deployments are performed only for the applications that have changed. The APIs are built with whichever technology the team and/or company decide so long as it works over a common protocol – typically HTTPS. If you are familiar with the concepts of Web APIs and/or Microservices, this group encompasses those concepts.

Web APIs

Some examples of web API responsibilities that an application requires include data access, logging, and usage analytics. Interestingly, none of these concerns require any knowledge of the Angular application. In fact, they could serve many different front-end applications.

Authentication

Authentication at this level is typically handled directly between the Angular application client and the Web API server. There are many ways to do this but today's solutions generally use some form of JSON web tokens to maintain the user's identity.

Internationalization

At this level, any assets requiring i18n would be handled by the web API using server-side techniques. Again, this has no coupling to the Angular application beyond the API contract.

A Case for Bundling

Sometimes, applications are small and the API that they access is small. In this case, you may decide to keep this functionality together in the same application. They share the same build and the same deployment. Sometimes the effort to split these functions isn't greater than the payoff.

In this case, consider your development and design carefully as to avoid creating unnecessary coupling between the concerns. The web API may one day 'grow up' to need its own project so develop accordingly.

Final Thoughts

Every application is different. Hopefully by reading about how application concerns create dependencies between the server and the Angular application, you can apply these considerations to your own architecture.

One thing you might have noticed, there's no discussion of development tools that integrate with the server. This is a topic for a future post so stay tuned.

Ultimately, there is no one way to design an application. However, by knowing your options, you're better equipped to make lasting design decisions for your project.

What do you think? Is there functionality you prefer to run on the server? The client? Please share in the comments.

ASP.NET Core – Migrating to MSBuild

Migrating to MSBuild Header

This post continues the theme of exploring project structures for Angular and ASP.NET Core applications. The ASP.NET Core framework is in the midst of a transition to a new MSBuild-based project configuration. While there is material to help you start with MSBuild from scratch, many if not most of the published ASP.NET Core examples use the JSON-based project system. By learning how to migrate an existing application to the new MSBuild system, you can leverage the existing code and learn the new system – it's the best of both worlds.

There have been a couple high-profile posts recently around migrating from project.json to MSBuild from Nate McMaster and Scott Hanselman. This post is an overview of the MSBuild migration to help put these recent conversations in context. Why is Microsoft doing it? How can you migrate easily? The post covers these topics and includes links and tips to help with your own migration.

Moving to MSBuild

MSBuild, also known as the Microsoft Build Engine, is an XML-based project system for processing and building software. It's designed specifically for the .NET Framework and Visual Studio but is capable of processing other types of software and frameworks.

When .NET Core was introduced, ASP.NET Core was one of the first application targets available. To make the platform more attractive to open-source web developers, ASP.NET Core adopted a JSON-based project system defined in a project.json file. Looking at Node.js, everything is JSON-based as opposed to XML so this was a sensible design choice to attract new developers.

Prior to .NET Core, .NET projects were all based on MSBuild (or an MSBuild-like system). Typically, the developer didn't have to worry about this. Most projects started from built-in Visual Studio templates and Visual Studio automatically handled updates to project files (.csproj, .vbproj, etc.). Occassionally you had to resolve merge conflicts in the project file because it contained a list of each file in the project which was represented by its own XML node. If two developers independently modified the list of files in a project, this could result in a merge conflict but these issues were typically easy to resolve.

After .NET Core debuted, it quickly positioned itself as the framework for all .NET-based application targets including Universal Windows Platform (UWP) and Xamarin. Non-web developers didn't see the project.json file as an upgrade. They were used to using MSBuild and wanted to continue to use it. So for the greater good of the existing .NET community, Microsoft announced they are going to re-standardize on MSBuild as the build system for .NET Core.

Microsoft has added new capabilities to MSBuild. It went cross platform in 2015 and Microsoft announced enhancements for the build engine. Read more about them in Microsoft's blog post. The first MSBuild-based SDK 'alpha' was released in November, 2016.

New CLI Command, "dotnet migrate"

To aid in the transition to the MSBuild project system, the dotnet command-line interface (CLI) now includes the dotnet migrate command. This command takes a project using JSON-based configuration and converts it to a .csproj file. The command is available in dotnet CLI version 1.0.0-preview3-004056 or later.

The utility carries out several actions. First of all, it takes your existing project.json, global.json, and .xproj files and moves them to a folder named backup. If you are using source control, you can safely delete this folder.

The second thing the utility does is generate a new .csproj file from the contents of the project.json file. Before you delete the old file, consider taking a look at how the project.json and .csproj files compare.

Most of the contents of the project.json convert to PackageReference elements:

<PackageReference Include="Microsoft.AspNetCore.Mvc">
    <Version>1.1.0</Version>
</PackageReference>

There is a slight difference for tooling dependencies. They are added as DotNetCliToolReference elements.

<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools">
    <Version>1.0.0-msbuild1-final</Version>
</DotNetCliToolReference>

For executing npm scripts in your ASP.NET build to pre-process your TypeScript or Sass code, the new MSBuild script looks like this:

<Target Name="PrepublishScript" BeforeTargets="Publish">
    <Exec Command="npm install" />
    <Exec Command="npm run tsc" />
</Target>

If you are distraught over the project file moving from a concise JSON schema to a specialized XML-based schema like MSBuild, don't get too upset yet. First, you can continue to use project.json in the short-term by including a global.json file in your project. In the long term, Microsoft has stated they are looking at how to generate MSBuild-based configuration so that ideally you don't have to write it yourself. The dotnet migrate command is an important first step to this commitment. However, as an ASP.NET developer you will most-likely benefit from having a basic understanding of MSBuild.

Tips

There is a great post discussing the details of migrating from project.json to MSBuild in Nate McMaster's conversion guide. Also, take a look at the MSBuild documentation to gain a general understanding of the build system.

One important detail to note is that your global.json file must reference a version of the CLI that supports dotnet migrate (1.0.0-preview3-004056 or later). If you see the error No executable found matching command "dotnet-migrate", look to update the sdk in your global.json file.

This last tip is anecdotal. It did cost me time so hopefully describing it may help someone else. While not completely sure the reason yet, there was an issue executing commands, in this case npm scripts, before or after the "Publish" target. If you experience this issue, try using a different target such as Build.

<Target Name="NpmCommands" AfterTargets="Build">
    <Exec Command="npm install" />
    <Exec Command="npm run tsc" />
</Target>

Finally, look for more resources from Microsoft. They are working to deliver an "RTM quality" version of the SDK in early 2017 so expect many updates to documentation and templates leading up to the release.

Conclusion

The dotnet migrate tool is very helpful. I have found works well at least with smaller projects. This is a considerable shift in configuration and Microsoft has done commendable work to automate the process. Looking forward, it will be interesting to see how they make this configuration easier for web developers coming new to the platform.

Have you been working with the MSBuild project system in .NET Core? What have been your pitfalls or successes? Please share in the comments.

Great Angular, ASP.NET Core Starter Templates

Great Angular, ASP.NET Core Starter Templates Title

This post exists to provide hope. After the somewhat hesitant reaction to last week's webpack post, this post highlights two great Angular and ASP.NET Core starter templates. These starter projects not only contain configurations for webpack 1 and webpack 2, there are a ton of other Angular and ASP.NET features implemented for you.

ASP.NET Core Template Pack

ASP.NET Core Template Pack - Angular Starter

The first project template to note comes from the ASP.NET Core Template Pack by Mads Kristensen. The template pack is a Visual Studio Extension containing multiple templates for ASP.NET Core. The collection includes a helpful Angular template.

Key Features

The hallmark feature of the template is Angular Universal. This framework enables server-side Angular rendering when the application is initially requested from the server. Angular Universal decreases the initial page load time by rendering the first request on the server instead of requiring the client to wait for the application to download before rendering. Subsequent route changes are all rendered client-side. For any application that requires minimum load times, this framework is a must-see.

The template also uses webpack version 1. For anyone working on integrating webpack into their applications, every example helps. This template doesn't use the latest loaders that the folks on the Angular side of the community are using. It does however accomplish the primary goal by compiling combined scripts. And being that it's using Angular Universal, there are webpack configurations for both the client application and the server rendering portion.

The template also implements webpack's hot module replacement feature. This is a development feature where the client-side code is replaced in the browser via a WebSocket when the source module is edited on the file system. If you've ever used a development server with automatic refresh like Browser Link or Browsersync, then it's like that – except without the full page refresh. You should check out the template just to try out this feature – you may never go back.

The previously mentioned features are configured with the help of Steve Sanderson's ASP.NET Core JavaScript Services. This library is part of ASP.NET Core on GitHub and provides useful integrations for single-page application (SPA) frameworks including Angular. The template includes simple, foundational examples for routing and data access as well as Docker container configuration.

Gotchas

Currently, if you are looking for the very latest in front-end Angular features, this template doesn't have them. It's using webpack version 1 versus webpack version 2 and doesn't include all of the niceties that have been introduced with newer webpack loaders such as awesome-typecript-loader and angular2-template-loader.

Also, if you see an error like this when starting the template, it means you have to specify a prior version of ASP.NET using the global.json file.

Template Error

You can read more about the solution on GitHub.

Bottom Line

This is a stable template that highlights the main integration points between ASP.NET Core and Angular. For now, it might not have the most up-to-date client-side features but you can imagine these will come as the tooling comes to a final release (or when we all submit pull requests). Being a Visual Studio extension, it is optimized for the Visual Studio IDE and it provides a nice starting point.

To view the source for this template, check out its GitHub repository.

ASP.NET Core & Angular2 Universal Starter (Angular2Spa)

ASP.NET Core & Angular2 Universal Starter Diagram

This might be the best Angular on ASP.NET Core template available right now. It's actively developed by a member of the Angular Universal team, Mark Pieszak.

In fact during the course of writing this review, he fixed an issue that I was experiencing while working with the template for this article. The template contains some of the latest techniques and frameworks for building Angular applications on ASP.NET or otherwise.

Key Features

You can think of this project as a superset of the template currently in the ASP.NET Core Template Pack. It has the same base level of features and then adds on top of it. This template works in Visual Studio. It also contains configuration files to run in Visual Studio Code, complete with key bindings to initialize the dotnet build. It even uses the newer ASP.NET Core 1.1 assembly versions.

For the front-end tooling, the template uses webpack version 2 including many new loader patterns that you find in the Angular documentation. The example also makes use of an RxJS-based, Redux-like store via the NgRx library.

To help keep your code styles on par, this template uses codelyzer. Built on top of TSLint, codelyzer provides linting for TypeScript as well as the Angular Style Guide conventions.

Finally, this template configures unit testing with Karma and Jasmine integrated with webpack. It also includes end-to-end (E2E) tests using Protractor. These configurations alone can save you a dozen hours versus configuring yourself.

Gotchas

Certainly check out the README file for this project. It has a lot of great information on how to use Angular with or without this template and highlights areas where you may otherwise stumble. One other word of caution – this template leans on the bleeding edge so you may find some instability along the way. The maintainer so far seems to do a nice job keeping up with any logged issues.

Bottom Line

This is a must-see and must-watch starter template for ASP.NET developers using Angular. There is nothing more to say, take a look for yourself.

Final Thoughts

The Angular and ASP.NET frameworks are both evolving at a rapid pace and it can be difficult to keep current with the changes. These templates can help you start coding quickly and help you incorporate new technologies and patterns as they are published.

These are two of the best and more noteworthy starter templates for Angular and ASP.NET. Give them a try and share your thoughts below. If there are any other starter templates you find helpful, please let everyone know in the comments.

SystemJS to Webpack – Before You Begin

SystemJS to Webpack - Before You Begin Title

This is a primer discussing why to move from SystemJS to webpack in your Angular project. The post also describes some of the hurdles you may run into with this effort.

While it doesn't go into specific webpack configuration, this article aims to provide an overview for someone who has heard of webpack but doesn't quite understand why or how to get started. Specific details configuring webpack with ASP.NET Core are coming in future posts.

SystemJS – Starting Point

There are several posts on this blog with examples using SystemJS to mimic Node.js module resolution in the browser. While TypeScript understands how to resolve types by npm package name during development, SystemJS fills this need in the browser by mapping package names to specific script files within the npm packages. This is an effective and minimal way to setup an Angular 2 application to load its dependencies from npm and get going quickly.

After starting with SystemJS, applications (even small ones) quickly grow to contain hundreds of ES2015 modules that are then downloaded by the browser to execute the application. This is probably not a problem during development when the browser and the server are on the same machine.

At some point, however, you may want to host your application for others to see. The performance hit of loading this many modules becomes noticeable. This situation leads to creating some type of build combining these hundreds of requests into only a handful.

Whereas SystemJS manipulates the browser to understand node module resolution, webpack (and similar build tools) manipulate the code to accommodate the browser's needs. Whether SystemJS or webpack, you continue to code the way that makes you the most productive with as many ES2015 modules in as many files as make you happy. Unlike SystemJS, webpack provides the browser with a streamlined payload to load the application as efficiently as possible.

Destination Webpack

Webpack at its core is a JavaScript module bundler meaning it takes JavaScript modules from separate files and combines them into one file. Webpack can be extended, though, by using loaders which allow you to bundle other types of files. So, while webpack doesn't understand TypeScript natively, it processes .ts files by using a loader.

Webpack has another extensibility mechanism called plugins. Where loaders handle specific file types, plugins process the contents of the loaded files. Plugins, for example, are responsible for minifying code where variable names are shortened and whitespace is removed.

One aspect of webpack that is different from a tool such as grunt or gulp is that it is more declarative meaning you configure an object literal and that object defines what should happen when you run the webpack command. The declarative nature of webpack ideally requires less configuration code and should lead you into a build that is more optimized than if you had to wire the pieces up yourself.

There are two other npm packages that carry the webpack name but are not the bundler, itself. These packages work with the bundler to improve the development experience. They are webpack-dev-server and webpack-dev-middleware.

The webpack-dev-server npm package is a lightweight development server based on Node.js and Express. It has all the basic development server features and includes hot module replacement. Hot module replacement (HMR) is a process where the development server uses a WebSocket connection to replace the code of a given module in the browser when it has changed in the development environment. This does not require a full page refresh to reflect the updates making it seamless to view your changes in the browser during development.

The webpack-dev-middleware npm package is a little more esoteric. It runs as an in-memory store containing the build output as opposed to writing the output to disk. This can decrease the time between when you modify a file and when you can see the changes running in the browser.

Configuration Troubles

Currently in early 2017, webpack is moving from version 1 to version 2. This can lead to incompatibilities in the webpack tool chain. When configuring a webpack build yourself, expect to find out-of-date examples and see errors processing your build.

Not all loaders and plugins support both webpack 1 or webpack 2 and you may find yourself trying different versions of these npm packages with different versions of webpack. Throw in the fact that TypeScript is adding significant new features through all of this and it's a recipe for configuration troubles.

This isn't meant to scare you off, just be prepared. Expect to search through the GitHub issues of some of these frameworks looking for answers or expect to post issues yourself. It's not always clear which combination of settings are correct but the webpack community is by-and-large responsive and committed to this tooling.

This is an example of an issue you may find. While the TypeScript compiler allows comments in the tsconfig.json file as of version 1.8, some of the TypeScript webpack loaders will blow up if there are comments in this file. There is no helpful error message, it just throws an error that a property is not defined on a null reference.

It's likely these issues are resolved over time, but you should understand what you are up against.

Replacing SystemJS

Now that you know about webpack's advantages and potential pitfalls, what are the general steps required to replace SystemJS? This is a summary:

  • Move polyfill scripts from index.html into the webpack bundle
  • Compile and bundle the TypeScript files
  • Move any external component HTML templates and stylesheets inline
  • Add a reference to index.html for the new bundled resource

Move polyfill scripts from index.html into the webpack bundle

Many Angular tutorials instruct you to put polyfill dependencies directly in the index.html (or alternatively named default HTML) file. This approach works and will continue to work with webpack but you should consider moving these dependencies into the webpack configuration.

First, including these dependencies into a bundled request improves performance. Second, having all your script dependencies in one place decreases the time to find a given dependency – thus increasing maintainability. Third, webpack resolves dependencies through node module resolution meaning you add the package name to the configuration and you're done. Using SystemJS, you often must identify the correct script to load from within the npm package.

Compile and bundle the TypeScript files

While you could continue to compile TypeScript with the TypeScript compiler, the idea is to move everything into webpack. There are several loaders that handle TypeScript files and are generally straightforward to configure. A popular TypeScript loader in the Angular community now appears to be awesome-typescript-loader.

Move external component HTML templates and stylesheets inline

This one is Angular-specific. When you have components with external templates and/or stylesheets, Angular loads these files as separate requests. By using a loader like the angular2-template-loader, the build now can combine the contents of the external templates and stylesheets into the component script itself.

Note: Understand that by moving the templates and stylesheets inline, setting the @Component directive's moduleId property is unnecessary. Leaving the moduleId property set in the component can lead to issues. While the available tooling should most likely handle this, you may find you must account for this yourself by removing the settings manually or creating automation.

Add a reference to index.html for the new bundled resource

Finally, once you define the file(s) that webpack outputs, you must reference the new bundled file(s) in your main HTML file. As you may have guessed, there are even webpack plugins to handle this as well based off the webpack configuration (see html-webpack-plugin).

Additional Configuration

While the previous sections listed the necessary pieces of a basic webpack build. You have so many more options available to you to optimize your code. Some build steps to consider are: Ahead-of-time (AOT) compilation, using the wwwroot folder in ASP.NET Core, tree-shaking, running tests, and using the webpack development server with hot module replacement.

Tackling the Beast

So, you still want to get going with webpack? Where do you begin? There are many projects on Github and other sites that provide insight into how this tool works. It appears to still be hit or miss as far as quality. Looking at it from an ASP.NET developer's perspective, the guidance options are fewer. With that said, here are some links to get started:

None of these resources paint the full picture but they provide a good overview. In addition to these general resources, visit the documentation for the individual loaders and plugins to get details regarding compatibility with other packages.

You should consider creating your own webpack build from scratch. There are advantages to doing it this way. If you like knowing how these tools work, this is a rewarding way to learn, albeit a time-intensive one.

Focus on one piece of the build at a time. It's easier to identify which pieces of the build are failing and you can more easily investigate or replace that specific loader or plugin to compare results. Once you stabilize one part, move on to the next until you have the build that you want.

Start with the pieces outlined in the Replacing SystemJS section and continue from there.

More on the Way

You've learned why you should consider moving to webpack and the general approach to creating a webpack-based build. Again, this is just a primer. The plan is to ultimately provide you with a webpack configuration that works well with Angular and with ASP.NET Core. You will see more posts about webpack here soon.

For now, what are your favorite webpack resources? Did you build a template that others may find useful? Please share in the comments.

Your First Angular 2, ASP.NET Core Project in Visual Studio Code – Part 6

Angular2, ASP.NET Core, Visual Studio Code, Part 6

Derived from photo by Markus Spiske / raumrot.com, CC-BY

This is the last in a series of posts teaching you how to create your first Angular 2 application with ASP.NET Core in Visual Studio Code. Here is the list of posts:

This article discusses an important part of the integration between client and server – routing. Angular 2 has its own router and so does ASP.NET Core. In the following sections you learn to setup routing in Angular 2 and then how to support the Angular 2 routing with ASP.NET Core.

This post addresses the high-level concerns of integrating these two routing systems. For more information on the individual routing features for each framework, read about Angular 2 routing here and ASP.NET Core routing here.

.NET Core SDK Preview 3: This tutorial uses .NET Core SDK Preview 3 which is available on GitHub. This version includes 'alpha' support for MSBuild-based projects that use .csproj configuration instead of project.json configuration. Microsoft announced that MSBuild is the common project configuration for .NET Core based projects going forward. By using MSBuild, the goal is to better prepare you for future versions of the tooling.

If you would like to jump straight to the code, it's all on GitHub.

Refactor to Multiple Components

In order to implement routing for Angular 2, you need to have multiple components in the project.

Move the contents of AppComponent to a new component called PairingComponent which is responsible for pairing Sriracha with foods.

import { Component } from '@angular/core';

@Component({
    moduleId: module.id,
    selector: 'my-pairing',    
    template: `
        <h2>Pairing</h2>
        <input type="text" [value]="food" (input)="foodInput($event)"/>        
        <p>Sriracha sauce is great with {{ food }}</p>
    `,
})
export class PairingComponent { 
    food = 'kielbasa';

    foodInput(event: Event) {
        const target = event.target as HTMLInputElement;
        this.food = target.value;
    }
}

The AppComponent becomes the application shell including the navigation. For now, the PairingComponent is rendered directly in the AppComponent template.

import { Component } from '@angular/core';

@Component({
    moduleId: module.id,
    selector: 'my-app',    
    template: `
        <nav>
            <a href="/pairing">Pairing</a> | 
            <a href="/about">About</a>            
        </nav>
        <my-pairing></my-pairing>
    `,
})
export class AppComponent { }

Also, create a third component called AboutComponent which serves as a second view.

import { Component } from '@angular/core';

@Component({
    moduleId: module.id,
    selector: 'my-about',    
    template: `
        <h2>About Sriracha</h2>

        <p>This is what Wikipedia says about <a href="https://en.wikipedia.org/wiki/Sriracha_sauce_%28Huy_Fong_Foods%29">Sriracha sauce</a>:</p>

        <blockquote>It can be recognized by its bright red color and its packaging: a clear plastic bottle with a green cap, text in Vietnamese, English, Chinese, French, and Spanish, and the rooster logo. David Tran was born in 1945, the Year of the Rooster...<blockquote>
    `,
})
export class AboutComponent { }

Finally, you declare all of these components in the AppModule.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';
import { PairingComponent } from './pairing.component';
import { AboutComponent } from './about.component';

@NgModule({
    bootstrap: [ AppComponent ],
    imports: [ 
        BrowserModule,
    ],
    declarations: [ 
        AppComponent, 
        PairingComponent, 
        AboutComponent, 
    ],
})
export class AppModule { }

The app directory now looks like this:

component folder structure

Run your application to see the new navigation.

Navigation Screenshot

Configure the Angular 2 Router

To configure the AppModule routes, import RouterModule and Routes from @angular/router. The Routes type is an array of Route objects used to define the routes.

When navigating to http://localhost:5000/pairing the application should show the PairingComponent. When navigation to http://localhost:5000/about the application should show the AboutComponent. There is also a third scenario. When navigating to the root of the application, http://localhost:5000/, the application should redirect to http://localhost:5000/pairing as the default.

This is what the Routes array looks like:

const routes: Routes = [
  { path: '', redirectTo: '/pairing', pathMatch: 'full' },
  { path: 'pairing',  component: PairingComponent },
  { path: 'about', component: AboutComponent },
];

The pathMatch property must be set for all redirects. In this case, the value 'full' denotes that the redirect should occur when the path is at the application root or is otherwise empty ('').

Next, register these routes with the RouterModule and register the RouterModule with the AppModule.

This is the final code for the AppModule:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule, Routes } from '@angular/router';

import { AppComponent } from './app.component';
import { PairingComponent } from './pairing.component';
import { AboutComponent } from './about.component';

const routes: Routes = [
  { path: '', redirectTo: '/pairing', pathMatch: 'full' },
  { path: 'pairing',  component: PairingComponent },
  { path: 'about', component: AboutComponent },
];

@NgModule({
    bootstrap: [ AppComponent ],
    imports: [ 
        BrowserModule,
        RouterModule.forRoot(routes),
    ],
    declarations: [ 
        AppComponent, 
        PairingComponent, 
        AboutComponent, 
    ],
})
export class AppModule { }

Finally, the Angular router depends on a base element with href defined. You add this in the head of index.html so that Angular can update the browser's address bar correctly. This is the updated index.html code:

<!DOCTYPE html>
<html>

<head>
    <title>Angular 2, ASP.NET Core Starter</title>
    <base href="/">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Polyfill(s) for older browsers -->
    <script src="node_modules/core-js/client/shim.min.js"></script>

    <script src="node_modules/zone.js/dist/zone.js"></script>
    <script src="node_modules/reflect-metadata/Reflect.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>

    <script src="systemjs.config.js"></script>
    <script>
        System.import('app').catch(function(err){ console.error(err); });
    </script>
</head>

<body>
    <my-app>Loading...</my-app>
</body>

</html>

Configure the Navigation

The last step to configure the Angular routing is to configure the navigation to utilize the routes. To accomplish this, you modify the AppComponent template in two significant ways.

First, instead of including the my-pairing element in the AppComponent template, replace it with the router-outlet element. This is a placeholder where the router renders the component matching the current route.

Finally, you replace the href attribute with the routerLink attribute. This is a directive instructing Angular to register the click with the router instead of the default href behavior.

The final code for the AppComponent looks like this:

import { Component } from '@angular/core';

@Component({
    moduleId: module.id,
    selector: 'my-app',    
    template: `
        <nav>
            <a routerLink="/pairing">Pairing</a> | 
            <a routerLink="/about">About</a>            
        </nav>
        <router-outlet></router-outlet>
    `,
})
export class AppComponent { }

At this point, run the application using Ctrl+Shift+B and start the browser using npm run chrome which you configured in part 5. Notice how the application defaults to the /pairing URL. Clicking on the link loads the appropriate component for that specific URL.

Working Angular 2 Routes

There's still one problem. When you go directly to a route URL like http://localhost:5000/about from the browser's address bar, you see a 404 error. This is a result of the fact that even though Angular knows how to reconcile this URL, the server does not.

In the next section, you configure the ASP.NET MVC routes to return the Angular application when it doesn't recognize the route.

Add ASP.NET Routing

In order to configure ASP.NET routing, you must install the ASP.NET MVC package. Add this PackageReference to the .csproj file and then run dotnet restore from the terminal.

<PackageReference Include="Microsoft.AspNetCore.Mvc">
    <Version>1.1.0</Version>
</PackageReference>

Once the package is installed, create a directory at the root of your project called Controllers. Inside this directory, create a file called HomeController.cs. In this file, create a HomeController class which inherits Controller. This is the code.

using System.IO;
using Microsoft.AspNetCore.Mvc;

public class HomeController : Controller
{
    public IActionResult Index()
    {
        var fileName = "index.html";
        var contentType = "text/html";

        string filePath = Path.Combine(Directory.GetCurrentDirectory(), fileName);
        string fileContents = System.IO.File.ReadAllText(filePath);

        return Content(fileContents, contentType);
    }
}

In ASP.NET MVC, controllers are where a request is processed and a response is constructed. In this controller, the Index method reads the index.html file containing the Angular application and returns the file contents as a text/html response to the browser. This is essentially the same response that the browser receives when requesting index.html directly. Once the application is loaded into the browser, the Angular router takes over.

In order for the HomeController to do its thing, you must configure the ASP.NET MVC router to direct all of the incoming requests to the Index method.

In the Startup.cs file, you have to add a couple new configurations. First, ASP.NET MVC is configured as a service which requires the Startup class to implement a ConfigureServices method. Also, you configure the routes in the existing Configure method. The new Startup.cs code looks like this:

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseDefaultFiles();
        app.UseStaticFiles();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{*url}",
                defaults: new { controller = "Home", action = "Index" });
        });
    }
}

The MapRoute method takes a configuration object. The template field defines the URL pattern that matches the route. Because there is only one variable defined in the template and it uses the asterisk, this route essentially handles all requests that haven't already been handled by the UseDefaultFiles or UseStaticFiles middleware. Furthermore, the defaults field directs all of these requests to the HomeController and it's Index action method.

At this point, run your application. In the browser, go directly to http://localhost:5000/about and you will see that the application loads from the server. Once the Angular application loads, it applies the correct route on the client.

Routing Integration

The End

This brings the final part of this Angular 2, ASP.NET Core, and Visual Studio Code journey to a close. You have learned a lot about configuring these frameworks and tools to work together. You've learned your way around Visual Studio code. You configured an Angular 2 and ASP.NET Core application so that both frameworks play well together. You created a basic Angular 2 application and automated tasks with npm and Visual Studio Code.

But you have only scratched the surface. This is just the beginning. What was your favorite discovery? Which topics are you most interested in learning about more? Leave a comment below and have fun with your new tools!

Your First Angular 2, ASP.NET Core Project in Visual Studio Code – Part 5

Angular2, ASP.NET Core, Visual Studio Code, Part 5

Derived from photo by Markus Spiske / raumrot.com, CC-BY

This is part five in a series of posts teaching you how to create your first Angular 2 application with ASP.NET Core in Visual Studio Code. Here is the list of posts:

This post is all about automating common development tasks with npm scripts and Visual Studio Code. You learn how to install and clean dependencies, launch browsers, automatically rebuild your .NET code, and setup a build task in Visual Studio Code.

Mac and Linux Users: The commands in this article related to cleaning dependencies and launching browsers are specific to Windows. You can still use npm scripts on Mac and Linux by replacing the Windows commands with those for your environment. Details for specific commands are found readily through your favorite search engine.

.NET Core SDK Preview 3: This tutorial uses .NET Core SDK Preview 3 which is available on GitHub. This version includes 'alpha' support for MSBuild-based projects that use .csproj configuration instead of project.json configuration. Microsoft announced that MSBuild is the common project configuration for .NET Core based projects going forward. By using MSBuild, the goal is to better prepare you for future versions of the tooling.

If you would like to jump straight to the code, it's all on GitHub.

Note: If you have been following along with the series from the beginning, you might have noticed that this post was previously listed as being about Browser Link. Unfortunately, this feature still appears to be heavily tied to the full Visual Studio IDE. The tooling story for ASP.NET Core and Visual Studio Code continues to develop and you can expect more posts on these topics as additional tooling becomes available.

NPM Scripts

For this walkthrough, you are continuing from the npm script you built in part 3. While Visual Studio Code supports a variety of automation tooling, npm scripts are a discoverable and simple way to automate tasks for your project.

The scripts are all located in the package.json file under the "scripts" property. At this point in the walkthrough, this is the current version:

"scripts" : {
    "start": "tsc && concurrently \"tsc -w\" \"dotnet run\" "
},

This script compiles the TypeScript files and then runs the TypeScript compiler in watch mode alongside running the ASP.NET application. You invoke it by entering npm start in the terminal.

Notably, npm has built-in commands as well as custom scripts. For instance, start is a built-in command. You invoke it by entering npm start. However, if you take the same script and call it gyro, it would not be recognized by entering npm gyro because it is not a built-in command. You instead enter npm run gyro into the command line to invoke that script.

It's important to understand that the built-in commands sometimes have special behavior. You can see the full list supported by your version of npm by entering npm -h in the terminal and you can read more about these commands in the documentation.

Installing Dependencies

Part 3 of this series describes how to setup a package.json file and shows how to use npm install to download the dependencies from npm. In part 2, it similarly describes using dotnet restore to do the same thing for .NET Core dependencies. Instead of using these two commands, what if you only had to remember one to install all the dependencies in your project?

The npm install command is one of the npm commands with special behavior. You configure an npm script named install but the commands get executed after the default npm install command has finished. The is the perfect place to call dotnet restore. Add the following to the scripts property:

"scripts" : {
    // ... 
    "install": "dotnet restore"
},

Now when you enter npm install in the terminal, the dotnet dependencies install as well.

Cleaning the Project

In addition to installing dependencies, you should be able to easily delete out-of-date dependencies. Essentially, you need a set of scripts to delete the downloaded packages and build artifacts from the project directory. These commands work well on Windows for this purpose:

"scripts" : {
    // ... 
    "clean": "npm run clean:dotnet && npm run clean:npm",
    "clean:dotnet": "npm run clean:bin && npm run clean:obj",
    "clean:bin": "del /q .\\bin\\*.* && for /d %i in (.\\bin\\*.*) do @rmdir /s /q \"%i\" ",
    "clean:obj": "del /q .\\obj\\*.* && for /d %i in (.\\obj\\*.*) do @rmdir /s /q \"%i\" ",
    "clean:npm": "del /q .\\node_modules\\*.* && for /d %i in (.\\node_modules\\*.*) do @rmdir /s /q \"%i\" "
},

Notice the clean script is composed of multiple npm scripts. When calling multiple commands, concatenate them with two ampersands (&&). The bulk of the work is done with the clean:bin, clean:obj, and clean:npm scripts which delete the contents of the bin, obj, and node_modules folders respectively. Because these commands delete only the contents, they can be called repeatedly without throwing an error.

Also notice that calling these scripts requires the run command. For instance, to call the clean script you type npm run clean in the terminal.

With these scripts, whenever you get an updated version of the repository, type npm run clean follow by npm install in the terminal and you have a fresh copy of the required npm and .NET dependencies. You might even decide to create a new script that calls them both.

Launching the Browser

Another important development task is opening the browser, sometimes multiple browsers, to test your application. This too, is an automation candidate. Here are three commands for launching different browsers to the application URL:

"scripts" : {
    // ... 
    "edge": "start microsoft-edge:http://localhost:5000",
    "chrome": "start chrome http://localhost:5000",
    "firefox": "start firefox http://localhost:5000"
},

Once added, type npm run chrome in the terminal to startup Google Chrome at the development URL.

Watching ASP.NET Code Changes

If you look at the start script, tsc -w initializes the file watcher for the TypeScript compiler. This command watches the file system for any TypeScript file changes and automatically re-runs the TypeScript build. To duplicate this functionality for C# code, use the dotnet watch command.

The dotnet watch command is a dotnet CLI extension. You reference the tool by putting the following in the project's .csproj file:

<ItemGroup>
    <DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="1.0.0-msbuild2-final"/>
</ItemGroup>

You can now use your new npm install script to restore the .NET dependency or simply run dotnet restore to download the package. Once it's installed, modify the build script to use dotnet watch run instead of dotnet run. This is the full scripts property in the package.json file including the dotnet watch change:

"scripts": {
    "start": "tsc && concurrently \"tsc -w\" \"dotnet watch run\" ",
    "install": "dotnet restore",
    "clean": "npm run clean:dotnet && npm run clean:npm",
    "clean:dotnet": "npm run clean:bin && npm run clean:obj",
    "clean:bin": "del /q .\\bin\\*.* && for /d %i in (.\\bin\\*.*) do @rmdir /s /q \"%i\" ",
    "clean:obj": "del /q .\\obj\\*.* && for /d %i in (.\\obj\\*.*) do @rmdir /s /q \"%i\" ",
    "clean:npm": "del /q .\\node_modules\\*.* && for /d %i in (.\\node_modules\\*.*) do @rmdir /s /q \"%i\" ",
    "edge": "start microsoft-edge:http://localhost:5000",
    "chrome": "start chrome http://localhost:5000",
    "firefox": "start firefox http://localhost:5000"
},

Now you can make changes to your C# code while the application is running and when you save the file, the .NET project rebuilds without any developer intervention.

Key Binding for NPM Start

While npm scripts are already easily accessible through the built-in terminal, Visual Studio Code offers a way to map a build task to a keyboard shortcut.

The default build task key binding is Ctrl+Shift+B and it is configurable. To map the npm start command to this task, begin by pressing Ctrl+Shift+B from anywhere in Visual Studio Code. At this point, Visual Studio Code sees that you are using npm scripts and prompts you to create a tasks.json file within the .vscode directory. Press the Configure Task Runner button to create the file.

Configure Task Runner

Now that the file is created, modify the tasks property to map the npm start script. In addition, set the task's isBuildCommand property to true to associate the task with the build command key binding, Ctrl+Shift+B.

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "0.1.0",
    "command": "npm",
    "isShellCommand": true,
    "showOutput": "always",
    "suppressTaskName": true,
    "tasks": [
        {
            "isBuildCommand": true,
            "taskName": "start",
            "args": ["start"],
            "isWatching": true            
        }
    ]
}

Save the file and try out the new functionality by pressing Ctrl+Shift+B. You should see the application starting in the terminal. To terminate the task, press F1 and find the command to Terminate Running Task.

Terminate Running Task

You can create additional tasks out of the other npm scripts but Visual Studio Code limits you to having one task running at a time. Furthermore because this build task runs in watch mode, it may be running most of the time you are in the editor. Therefore, it makes sense to continue running your other npm scripts from the terminal.

Build Succeeded

You are now equipped to zip through your development workflow using npm scripts and Visual Studio Code tasks. If you're coming from the Visual Studio IDE, this gives you an idea of how to accomplish some of what the full-fledged IDE provides and hopefully further inspires you to customize the tasks that Visual Studio Code enables.

Now that you have gotten a glimpse at what is possible, what other automated functionality would you like to see? How have you configured Visual Studio Code to help you be more productive? Let everyone know in the comments.

Your First Angular 2, ASP.NET Core Project in Visual Studio Code – Part 4

Angular2, ASP.NET Core, Visual Studio Code, Part 4

Derived from photo by Markus Spiske / raumrot.com, CC-BY

This is part four in a series of posts teaching you how to create your first Angular 2 application with ASP.NET Core in Visual Studio Code. Here is the list of posts:

In this post, you write a 'Hello World' style Angular 2 application. You are introduced to components, NgModules, and template syntax. The walkthrough discusses how to bootstrap an Angular 2 application in the browser and along the way you learn how to better manage your TypeScript files in Visual Studio Code.

This post scratches the very surface of what Angular 2 offers. It's included in the series for completeness and to offer perspective regarding the framework's fundamental building blocks. It is not intended to replace the excellent documentation that the Angular team has produced. So when you get the chance, please take some time and go through the Angular 2 Tour of Heroes Tutorial to learn about the wider breadth of features available in the framework.

Note: If you have been following along with the series prior to this post being published, there is an update to the Part 3 Angular 2 configuration. Please ensure you have the @types/node package installed in your devDependencies. This typings library contains definitions for the module.id API used in this part of the walkthrough.

If you would like to jump straight to the code, it's all on GitHub.

Define the Root Tag

First, add a custom tag to your index.html file. Angular uses the custom tag as an identifier for where in the document to render the application. Any content between the opening and closing tags is replaced during the bootstrap process, so this is a convenient place to add a loading message or indicator. Within the body of your index.html page, add the custom my-app element:

<body>
    <my-app>Loading...</my-app>
</body>

Your First Component

It's time to create your first Angular 2 component. An Angular 2 component is essentially a JavaScript class adorned with the @Component decorator in which you define a template. The class encapsulates the behavior of the component and the template encapsulates the view. Angular does the work to wire the view to the behavior for you.

Components are the building blocks of your application. At the root of your application, is a component containing other components, composed together to form a user interface. This composition is sometimes called a component tree where the root component contains all of the other components in your application and leaf components represent the re-usable widgets of your application with which the user interacts.

Component tree

Create a file within your application's app directory called app.component.ts. Go head and add this component code:

import { Component } from '@angular/core';

@Component({
    moduleId: module.id,
    selector: 'my-app',    
    template: 'Hello, Angular 2 World!',
})
export class AppComponent { }

The @Component syntax is a decorator. This code adorns the AppComponent class and adds metadata information about the class. In this case, it denotes that this class is an Angular 2 component.

The import statement obtains the Component decorater from the @angular/core library. This import statement is an example of node module resolution which you setup in part 3 of this series. The Component decorator sets three properties, moduleId, selector, and template.

The moduleId property, when used, is generally set in this fashion. By setting it to module.id, you are supplying the current ECMAScript 2015 module's URL to Angular. This helps the framework load external templates and styles from the same relative location (URL) as the component's scripts. In this example, the component has no external templates or styles and thus setting moduleId is not required. However you may find it's easier to always set moduleId than to keep track of when you need it and when you don't.

Angular uses the selector property as a CSS selector to query a template finding all the elements that should be initialized as this component. For instance, when you use this component in a view, you define it as <my-app></my-app>. This selector is a tag selector, because it targets elements by tag name. But you can use other CSS selector types. If you prefer to define your components in markup by class (.my-app) or by attribute ([my-app]) simply change the selector accordingly.

The template property is the view or markup rendered for the component. In a moment, you will explore the template syntax more. It's important to note that there are two template-related properties available on the Component decorator: template and templateUrl. The templateUrl property points to a separate file containing the markup. For any template more than a couple lines, creating a separate file and using templateUrl is generally easier. You'll find in Visual Studio Code (and probably many other editors) that having the extra HTML syntax highlighting and auto-complete when writing in a dedicated .html file is more productive.

Finally, the Component decorator annotates the component class definition. The Angular 2 Style Guide recommends suffixing class names with the Angular object type which is why this class is named AppComponent but ultimately you have the freedom to decide which naming convention to use. Notice the class is exported using the export keyword so that it can be consumed in other ECMAScript modules as you will soon see. Finally, this component is very simple with no behavior which is why the class definition doesn't have much code yet.

Your First Angular Module

Angular 2 brings forward the concept of Angular modules from Angular 1.x although in quite a different form. In Angular 2, Angular modules are defined with the NgModule decorator. To distinguish from ECMAScript 2015 (ES2015) modules, this post will refer to them as NgModules.

First, what's the difference between an NgModule and an ES2015 module? You can think of ES2015 modules as encapsulated, reusable units of code whereas NgModules are encapsulated, reusable units of the application. NgModules are composed of ES2015 modules making them a sort of higher-order unit. Again coming from the Angular 1.x world, NgModules are very similar conceptually to angular.module. If you are coming from a C#/.NET background, you can almost think of NgModules as namespaces or assemblies.

Angular requires you to have at least one NgModule in your application. For small applications this may be preferable, but as your code base grows adding additional NgModules may help you reason about the application.

For this example, create one NgModule to house and bootstrap your application. In the app directory, create the app.module.ts file and add this code:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';

@NgModule({
    bootstrap: [ AppComponent ],
    imports: [ BrowserModule ],
    declarations: [ AppComponent ],
})
export class AppModule { }

Notice that all the configuration occurs in the NgModule decorator. The bootstrap property is only necessary in this root NgModule. It instructs Angular to examine the existing DOM (parsed from index.html in this case), identifying the elements to replace with the components defined in bootstrap.

The imports property defines any NgModules that are consumed by this NgModule. Being this root NgModule is running in a browser, you must import the BrowserModule. The other NgModules in your application do not need to import that BrowserModule, only the root NgModule.

Finally, you declare all of the Components and Directives that belong to this NgModule in declarations. There are several other important properties with the NgModule decorator so refer to the documentation for more information.

Bootstrap the Application

Angular 2 provides multiple ways to bootstrap your application depending on where it is running (server versus browser) and whether it has been compiled ahead of time (AOT) or not. For this example, use just-in-time (JIT) compilation in the browser with platformBrowserDynamic to bootstrap the AppModule. In your main.ts file, replace the contents with this:

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule);

Save all of your files and start your application. From the terminal (Ctrl+`), type npm start to compile the TypeScript and start your ASP.NET Core application. Then view the application in the browser at http://localhost:5000. You see the message 'Hello, Angular 2 World!'

Hello, Angular 2 World!

Hide Generated TypeScript Files

At this point, you have three TypeScript files in your app directory and also six additional .js and .js.map files generated from the TypeScript build.

TypeScript generated files

Having three of each file name in the explorer pane can make it difficult to find the actual file you need. Furthermore, you don't really need to see the JavaScript and source map files during development. To address this, Visual Studio Code has settings to hide these files in the explorer pane.

There are two options when changing Visual Studio Code settings. The editor allows you to configure settings for your user profile on the development machine. In this way, all of your projects pick up the same settings on that machine but unless you manually back it up, those settings could be lost.

You also have the option to configure settings for your workspace which are easy to save in source control and restored on whichever machine you use. The downside is that they are only applied to that particular project. For this exercise, you are configuring workspace settings.

In the File menu, select Preferences, then click Workspace Settings. This creates a .vscode directory in your application root containing a file named settings.json.

File Menu, Workspace Settings

This file contains a set of matching curly braces. Within those curly braces, begin typing "files.exclude" but press TAB before the closing quote symbol. When you press TAB to trigger autocomplete, the default excluded files and directories are populated.

settings.json auto-complete

To that list of globs, add one to hide the source map files and one to hide the generated JavaScript files. When you are done the configuration looks like this:

{
    "files.exclude": {
        "**/.git": true,
        "**/.svn": true,
        "**/.hg": true,
        "**/.DS_Store": true,
        "**/*.js.map": true,
        "**/*.js": { "when" : "$(basename).ts" }
    }
}

When you save the file, you see that now only the TypeScript files are visible in the explorer pane.

No TypeScript Generated Files

Template Syntax

To wrap up this Angular example, you explore the Angular 2 template syntax. Open up the app.component.ts file to make changes to this component.

First, add a property to the component class called food and set it to your favorite food. Then, replace the template property with a basic template. Your component should look like the following:

import { Component } from '@angular/core';

@Component({
    moduleId: module.id,
    selector: 'my-app',    
    template: `
        <input type="text" [value]="food" />
        <p>Sriracha sauce is great with {{ food }}</p>
    `,
})
export class AppComponent { 
    food = 'kielbasa';
}

Go head and refresh your browser to see the changes. Also, ensure the request is not pulling from the browser cache.

Template Syntax Example

The first thing to point out is that the template is defined using the ES2015 template literal string syntax. This syntax uses the back-tick character (grave accent) and supports multi-line string values. TypeScript outputs ES5-compatible strings at compile-time.

Also, you see two examples of Angular-specific template syntax. First, the value attribute of the input is surrounded by square brackets []. This is called a property binding because it binds to the property of an element. In this case, the input's value property is set to the resulting evaluation of the component's food property. This syntax replaces the need for a specialized Angular directive. You are instead targeting the element's native properties, setting the bindings using an abbreviated syntax.

On the second line of the template, you see the double curly braces used {{ }} to bind to the same component property. This is the interpolation syntax. When changes to the component are made, the expression inside the curly braces is evaluated and the resulting value is coerced to a string and inserted into the DOM. This syntax is similar to Angular 1.x, although some of the rules around how expressions are evaluated have changed.

Now, edit the value in the text input. You see that it doesn't update the value in the paragraph. The binding only operates from the component to the view, not the other way around.

value doesn't change

To update the value, you wire-up one of the element's events with a method on your component. Instead of wrapping the event name in square brackets [], you wrap it in parentheses () For this example use the input event and create a method on the component class called foodInput to handle the event. This is called an event binding. Your component code should now look like this:

import { Component } from '@angular/core';

@Component({
    moduleId: module.id,
    selector: 'my-app',    
    template: `
        <input type="text" [value]="food" (input)="foodInput($event)"/>
        <p>Sriracha sauce is great with {{ food }}</p>
    `,
})
export class AppComponent { 
    food = 'kielbasa';

    foodInput(event: Event) {
        const target = event.target as HTMLInputElement;
        this.food = target.value;
    }
}

Notice in the template, the $event argument is passed to the foodInput method. This represents the argument that you would receive if you had handled the event in the DOM. Furthermore, look at the typings applied to the method. Both the Event and HTMLInputElement types help you use the API in the method. Ultimately, you take the new value from the event arguments and set it to the food property on the component which in turn updates the binding in the template.

value does change

In the past, you may have used two-way binding in Angular 1.x. Two-way binding is still around but the Angular framework is designed to support uni-directional (one-way) data patterns more easily out of the box. Read more about the template syntax here.

In Summary

You have now built an Angular 2 application sitting on top of ASP.NET Core from scratch. In this post, you learned how to bootstrap your application and learned about some of the fundamental building blocks of Angular 2 including components and NgModules. You also learned how to customize the settings in Visual Studio Code to hide files generated by TypeScript.

In the next post, you smooth out some of the rough edges with the development experience. Wouldn't it be great if your browser automatically updated after every code change? That's what part 5 covers so stay tuned.

How is your Angular 2 development going? If you used Angular 1.x, do you find that the frameworks are concept compatible? In what ways? Let everyone know in the comments.