Wednesday, October 11, 2017

Multiple solutions for Angular Ahead of Time (AOT) Compilation

Copyright from: blog.craftlab.hu

When we started developing new applications at Emarsys in the early stages of Angular (2 beta), the first thing we noticed is the growing size and slowing speed of the application. The size of the unminified source code quickly grew above 3 Mbs and took multiple seconds just to become responsive.

Just-in-Time (JIT) compilation

The main reason for this was that we were using JIT compilation. It creates a performance penalty by parsing the component templates every time the user opens the web page. The parsing also needs the compiler bundled into the application. It is the part that transforms HTML templates into runnable code. The compiler can take up half of the bundled code size, which is a huge portion.


We generate the source code at build time and JIT compilation starts to parse the templates at run time. Only after this can the application start with the generated code.

Ahead-of-Time (AOT) compilation

We can cope with this performance penalty if we move the compilation out of the run time (browser) to the source code generation. It statically analyzes and compiles our templates at build time.
Ahead-of-Time (AOT) compilation
This way compilation happens only once at build time and we no longer need to ship the Angular compiler and the HTML templates into the bundle. The generated source code can start running just after downloaded into the browser, no previous steps are needed.
The AOT compilation turns this HTML template
into this runnable code fragment.

Benefits of AOT compilation

  • Smaller application size (Angular compiler excluded)
  • Faster component rendering (already compiled templates)
  • Template parse errors detected earlier (at build time)
  • More secure (no need to evaluate templates dynamically)
For AOT compilation we need some tools to accomplish it automatically in our build process. Currently two solid solutions exist. Both methods work, but they serve different purposes and have different advantages and disadvantages.

Solution 1: ngc command line tool

The ngc command line tool comes with the package @angular/compiler-cli. It is a wrapper around the Typescript compiler (tsc). You can specify the files to be compiled within tsconfig.json with the files and excludes field. Compiler specific options can be placed inside the angularCompilerOptions property.
When running ngc, it searches for the entry module (it gives the context to the compilation) and the corresponding components, directives and pipes. For every one of them it compiles and outputs an .ngfactory.ts suffixed Typescript file where the compiled templates reside. The compiled files are generated next to the original file by default. The destination can be modified by genDirinside angularCompilerOptions.
It also generates the transpiled files from Typescript to Javascript besides the compiled factory files. These files represent the uncompiled Typescript files with the description of the original classes next to them in a .metadata.jsonsuffixed file. These files are not needed to run the application in AOT mode. They only come in handy when building an Angular library that supports AOT compilation.
To use the newly generated files, we will have to change the bootstrap of the application.
We need to change the module file to the .ngfactory.ts suffixed one
and import the bootstrap from @angular/platform-browser. The @angular/platform-browser doesn’t include the compiler, making a huge gain in file size.
After generating the AOT compiled Typescript files another step is needed where we bundle the application.
Advantages
  • It can always be used with the newest version of Angular just after it has been released
  • After compilation any kind of bundling tool can be used
  • Outputs metadata files for library development
Disadvantages
  • Only supports HTML in templates and CSS in styles.
  • No watch mode yet
  • Need to maintain AOT version of the bootstrap file
Example repositories

Solution 2: @ngtools/webpack plugin

The next package @ngtools/webpack is a plugin for Webpack 2 published as part of the Angular CLI repository. It gives a loader and a plugin to set up the configuration.
The plugin needs the location of the Typescript configuration and the entry module of the application. The entryModule property consists of the file path and the exported module class divided by a hashmark. With these it can run the AOT compiler and generate the factory files.
One big difference here is that it won’t transfer the factory, metadata and transpiled JIT Javascript files to the filesystem. It will only bundle the application based on the factory files, which only exist inside Webpack’s memory filesystem. It also searches for the entry point and transforms the bootstrap file automatically to become suitable for AOT compiled files.
The loader inside the rules property enables to use any kind of file type inside the component’s decorator templateUrl and styleUrls property.
For example SCSSLESS for stylesheets and PUG for templates. It replaces the relative URLs in templateUrl and styleUrls to require statements. Also lazy loaded modules on routes transpiled to import statements and the sub-modules are also AOT compiled with the main application.
This loader basically does the job of awesome-typescript-loader + angular-router-loader + angular2-template-loader and adds AOT compilation to the chain.
Advantages
  • Custom file types available for templates and styles through Webpack loaders (SCSS, PUG,…)
  • No separate process for compilation
  • Watch mode for AOT compiled files
  • No need to maintain AOT version of bootstrap file
  • No output to disk for separate *.ngfactory.ts files
Disadvantages
  • Can only be used with Webpack 2
  • Need to wait for new versions after Angular release to Angular CLI repository catch up
  • Compatible with current version
  • Not good for AOT compatible package publishing, because it doesn’t output separate compiled files
Example repositories

Solution 3: @ultimate/aot-loader plugin

A brand new Webpack 2 plugin (currently in beta) backed by the team behind Ultimate Angular. It gives a loader and a plugin to set up the configuration.
@ultimate/aot-loader is very similar in configuration and in abilities to the Angular CLI plugin. The factory and metadata files are only generated to the memory file system. The entry point is also transformed to load the factory files instead of the regular ones. Lazy loaded modules are transpiled and split into different chunks apart from the main bundle.
Loaders inside rules enable us to write templates and styles of components in the desired extension (SCSS, PUG, etc.).
Advantages
  • Same advantages as for the Angular CLI package
  • Compatible with Angular 4
Disadvantages
  • Can only be used with Webpack 2
  • Not good for AOT compatible package publishing, because it doesn’t output separate compiled files
Example repositories

Summary

It doesn’t matter which solution you choose, your application can greatly benefit from AOT compilation through size and speed. It halves the size of a small to medium sized application and multiplies it’s start up speed. If you are only using HTML for templates and CSS for styles or using a different build system from Webpack or developing a package in Angular 2, ngc can be a good fit. Otherwise I would stick with the @ngtools/webpack or the @ultimate/aot-loader plugin and enjoy it’s benefits over the command line solution.
If you want to dive deeper into AOT compilation,
you can read the official documentation also.

Thanks for reading! If you liked this story, please recommend it by clicking the ❤ button on the side and sharing it on social media. Follow me on Medium or Twitter to read more about Angular!
Special thanks to Wassim Chegham for the images about AOT and JIT compilation.

Solution Management with Dynamics CRM 2016

Copyright from: www.inogic.com

Introduction

The only supported way of transferring customizations from one CRM organization to another has been through Solutions. The concept of Solution when first released in CRM 2011 was a breakthrough considering before then there was no concept of IP protection. With Solution Management came the concept of Managed and Unmanaged Solutions.
Managed a way to protect your IP with an easy concept of install and uninstall.
Unmanaged more what was to be used in DEV environments.
Managed Solutions created dependencies for them and soon it was realized that Unmanaged was the way to go unless you are an ISV and packaging a solution and want to protect your IP.
But even though Solution management was better than methods that existed prior to CRM 2011, and became the norm for ISV solutions, it still had scope for huge improvements to avoid customer customization conflicts with ISV solutions. Over the past two versions there were not major improvements made in solution management but with 2016 the solution management has been totally revamped. Much greater control over what you want to include in your solution.

Solution Components

In the earlier versions, when you added an entity to the solution, it by default included all the entity components like fields, relations, business rules and even entity properties like, Auditing or Enable for Mobile etc. You did not have control over what you included and quite often the customers would themselves make customizations their end like say enable Auditing or Enable for Mobile etc. The entity properties are usually customized by the customers depending on their requirements and importing a managed solution would overwrite it without the customer’s knowledge L

Now when you add an entity to a solution, the following window comes up allowing you to select the components of the entity that you want included in the solution.

Solution Management


All of the components that are included in an entity are listed out for you to choose what you want included. Notice the two checkbox at the top,

Include entity metadata: it will include entity properties like Auditing, Mobile, Quick Create settings etc.

Add All Assets: this will include all components by default in the solution. Note once you have included all assets in a solution you are not allowed to remove any components from the solution so be careful about the choice you make.

Note: To bring back the above screen after you have clicked on finish and added the entity to the solution use the Add Subcomponents button.



I had selected only 2 fields so in the screen below you will see only those 2 fields listed for the entity no other components were selected.

Solution Management in crm


We now make change to the first name to increase the length to 155 and the auditing is not enabled for this entity in this organization.

Now when this solution is exported, it should only overwrite the two fields in the destination org. No changes should be reflected in the entity metadata in the destination org.


Here is how the first name field and audit settings looks like in destination org before the solution import.

Solution Management in crm 2016

This is what the solution looks like now

Solution Management in 2016


Now when you import the managed solution to this org, it should neither override the City length nor the Auditing settings

crm 2016 Solution Management


The Audit settings were not modified. Now here is what the first name looks like after import

Dynamics crm 2016 Solution Management

Conclusion

So only the items you intended to take to the other system are affected by the import. No other items are overwritten. Something that the earlier solution framework did not provide. Apart from the ability to pick and choose, the solution management now goes a step further to provide feature to create Patches for your solution, which is a common practice in product life cycle. We will check that in our next blog.


Solution Patching in Microsoft Dynamics CRM 2016

Copyright from: solution-patching-in-microsoft-dynamics-crm-2016

Introduction

In our earlier blog we looked into the enhancements made to the way solutions can be created in Microsoft Dynamics CRM 2016. Now moving forward we will look at a common scenario of sending out Patches for your solution. Often it happens that you may need to update a few components of your managed solution and ideally would like to have a way to only have those shipped and then have a way to compile all of these patches in the next release of the solution. This helps with better versioning control and management of the solution assets.

Patches


Taking it forward from our previous article, here is what our solution looked like.
Solution patching

Keep your eye on the Version number of the solution as this is one of the critical thing which will come to notice as we move ahead.
Now suppose due to some requirement changes I have to increase the maximum length for “First Name” field of Contact from 155 to 175.
Since this field was a part of the earlier solution that we had and this is the only change we need to make to that solution, we will go ahead and create a patch for the original solution

Use the “Clone a Patch” button added to the solutions views

Solution patching in crm

Notice the other buttons as well “Clone Solution” and “Apply Solution Upgrade”, this completes the entire solution management architechture.

clone to patch

It is a good practice to increment the version number for a proper version management of the solution. Since this is a patch it only allows you to modify the last 2 digits in the version.
This creates the following new solution.

Solution patching in crm 2016


Add only the Contact “First Name” field to the solution and update the length as shown below.

Solution patching in dynamics crm

When you import this patch on the client environment this solution will be applied on top of the base solution and only the “firstname” field will be updated.

Solution patching


You can create multiple patches for a solution. To create another patch you would select the original solution and click “Clone a Patch”.

Solution patching


The original solution can no longer be modified.

Solution base solution


In the Target system, you can delete the managed solution of a patch without affecting the base solution installed there.
The patches don’t have a dependency on each other, so in the target system I deleted the first patch that was imported and then imported the second patch and it works just fine. So that’s huge plus, since one of the problems with earlier solution management architecture was the dependencies that would be created between managed solutions. So here there is no dependency of the patches amongst them. But of course they do need the base solution present since they are patch for the base solution.

Solution patching in ms crm


Uninstalling the base solution on the target also automatically uninstalls all the patches that were installed for the base solution.
When you want to plan your next version of the solution, you usually want to rollup all of the patches that were released for the base solution into the new solution, before you can add new changes in there. This can be done using the “Clone Solution” button.

Solution patching in crm 2016

Now this time, you are only allowed to change the major and minor parts of the version.
Once the operation completes, you will find the patches deleted and the base solution version updated.

Solution patching

This solution is now available for editing as well.
When the Upgrade solution is imported on the target system, it auto detects this to be an upgrade to an existing installed package and notifies you of the same.

Solution information

On the next step of the import wizard, you get the option to choose if you want this imported as “Holding Solution”. This option will show up and checked by default if the target organization has base solution and patches for base solution installed. You can learn more about the “Holding Solution” concept here

upgrade solution

When the solution import completes, you see a new option “Apply Solution Upgrade” since you chose to import this as a holding solution.

Solution patching - importing solution


If you do not choose to apply the solution upgrade, you will see three solutions in the target system.

Solution patching

Now choose the original Base solution on the target system and click on the “Apply Solution Upgrade” button to keep a single solution for the package instead of the three that appear now

Solution patching

If there were no patches installed in the target system and the “Stage for Upgrade” option is unchecked, you have the option to check it if you want. If you leave it unchecked it simply updates the solution and you do not need to “Apply Solution Upgrade”.

Note : We have explained all the above scenarios using Managed Solution. When we tried with Unmanaged solution we got error “Action could not be taken for few records before of status reason transition restrictions” while importing Unmanaged Solution patch. But we were able to successfully import the cloned Unmanaged Solution for the same.

Conclusion

Though I have only explored this using basic customizations to entities, the whole solution management framework from creating a solution to patching to moving it to the next release and similarly “upgrading solution” on the target system appears that, it would reduce if not end a lot of “solution import” woes of the ISV community.

You may also like to read : User Adoption Metrics that matter in your Dynamics CRM.

Saturday, July 22, 2017

How to setup an Angular 2 and TypeScript project with Visual Studio 2017

Copyright from: adrientorris.github.io

You can see the source code of this tutorial on my GitHub repository, here : Angular2 web app source code on GitHub.
Versions :
  • ASP.NET Core : 1.1.0
  • Angular : 2.2.0
  • TypeScript : 2.0.0
  • Visual Studio : 2017 RC

Create new ASP.NET Core web application

How to setup an Angular 2 and TypeScript project with Visual Studio 2017
  • Choose an empty project to start from zero
  • Choose no authentication
  • Don't enable the docker container support (I will make a tutorial on Docker next)
How to setup an Angular 2 and TypeScript project with Visual Studio 2017
How to setup an Angular 2 and TypeScript project with Visual Studio 2017

Create the MVC folders structure

What is MVC ?
MVC, for Model-View-Controller is an architectural pattern who separates an application into three main components :
  • The Model
  • The View
  • The Controller
The purpose of this architectural pattern is to build applications that are easily maintenable and testable, separating differents components. A best practice is to pair this architectural pattern with an N-Tier layers architecture.
  • Create the folder "Models", who contains classes that represent some data, validation logic and business rules
  • Create the folder "Views", who contains views who are the components that displays the user interfaces
  • Create the folder "Controllers", who contains the controllers, classes that handles the browser requests. Controllers handles and responds to user input and interaction
  • Create the "wwwroot" subfolders, who contains static files to serve, like JavaScript files, css and images
How to setup an Angular 2 and TypeScript project with Visual Studio 2017

Create a folder where put the TypeScript files

How to setup an Angular 2 and TypeScript project with Visual Studio 2017

Set TypeScript configuration

If TypeScript is the primary language for Angular application development, it can't be executed by the browsers directly; TypeScript must be "transpiled" into JavaScript using the tsc compiler, which requires some configuration.
To configure the TypeScript compiler and set your environment, you have two files to add :
  • tsconfig.json, the TypeScript compiler configuration file
  • typings, the TypeScript type definition files file

tsconfig.json

The TypeScript configuration file is required to guide the TypeScript compiler as it generates JavaScript files which are used by the browser.
How to setup an Angular 2 and TypeScript project with Visual Studio 2017
This is the default content when you add the tsconfig.json file to your project :

{
  "compilerOptions": {
    "noImplicitAny": false,
    "noEmitOnError": true,
    "removeComments": false,
    "sourceMap": true,
    "target": "es5"
  },
  "exclude": [
    "node_modules",
    "wwwroot"
  ]
}
So, what do we have in this file ?
The compilerOptions section is optional, if its null default values will be use. You can find the details of this section here : http://www.typescriptlang.org/docs/handbook/compiler-options.html
If you want more information about this file, you can read the documentation : http://www.typescriptlang.org/docs/handbook/tsconfig-json.html
For our project, we have to specify where the tsc can find our TypeScript files and where we want it generates the JavaScript files, and some other settings. This is the content we need :

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": true,
    "suppressImplicitAnyIndexErrors": true,
    "rootDir": "App",
    "outDir": "wwwroot/app"
  },
  "compileOnSave": true,
  "angularCompilerOptions": {
    "genDir": ".",
    "debug": true
  },
  "exclude": [
    "node_modules",
    "wwwroot"
  ]
}

TypeScript type definition files

Many JavaScript libraries, such as jQuery, extend the JavaScript environment with syntax and features that the TypeScript compiler doesn't recognize natively. This file tell the compiler about the libraries you load.

{
  "globalDependencies": {
    "jquery": "registry:dt/jquery",
    "jasmine": "registry:dt/jasmine"
  }
}

Add a NPM configuration file

What is NPM ?

NPM, for Node Package Manager, is a utility that aids JavaScript open source package installation, version and dependency management. NPM is distributed with Node.js, which is an asynchronous event driven JavaScript runtime, designed to build scalable network applications.
Angular 2 and its dependencies are delivered through NPM, so you need to add the NPM configuration file in your project, package.json.
How to setup an Angular 2 and TypeScript project with Visual Studio 2017
You will have an empty NPM configuration file :

{
  "version": "1.0.0",
  "name": "asp.net",
  "private": true,
  "devDependencies": {
  }
}
To add Angular 2 and its dependencies to your projects, you have to add some dependencies in your NPM configuration file :

{
  "version": "1.0.0",
  "description": "NO404 administration panel",
  "name": "no404 backoffice",
  "readme": "no404 backoffice",
  "license": "MIT",
  "dependencies": {
    "@angular/common": "~2.2.0",
    "@angular/compiler": "~2.2.0",
    "@angular/core": "~2.2.0",
    "@angular/forms": "~2.2.0",
    "@angular/http": "~2.2.0",
    "@angular/platform-browser": "~2.2.0",
    "@angular/platform-browser-dynamic": "~2.2.0",
    "@angular/router": "~3.2.0",
    "@angular/upgrade": "~2.2.0",

    "angular-in-memory-web-api": "~0.1.15",
    "core-js": "^2.4.1",
    "reflect-metadata": "^0.1.8",
    "rxjs": "5.0.0-beta.12",
    "systemjs": "0.19.39",
    "zone.js": "^0.6.25",

    "bower": "1.7.9",
    "jquery": "^3.1.0"
  },
  "devDependencies": {
    "@types/core-js": "^0.9.34",
    "@types/node": "^6.0.45",
    "concurrently": "^2.2.0",
    "gulp": ">=3.9.1",
    "gulp-concat": ">=2.5.2",
    "gulp-copy": ">=0.0.2",
    "gulp-cssmin": ">=0.1.7",
    "gulp-load-plugins": "^1.3.0",
    "gulp-rename": ">=1.2.2",
    "gulp-rimraf": ">=0.2.0",
    "gulp-tsc": ">=1.2.0",
    "gulp-uglify": ">=1.2.0",
    "gulp-watch": ">=4.3.9",
    "gulp-clean-css": "^3.0.4",
    "gulp-clean": "^0.3.2",
    "jasmine-core": "2.4.1",
    "tslint": "^3.15.1",
    "typescript": "^2.0.0",
    "typings": "^1.3.2"
  },
  "scripts": {
    "start": "concurrently \"npm run gulp\" \"npm run watch\" \"npm run tsc:w\"",
    "postinstall": "typings install",
    "tsc": "tsc",
    "tsc:w": "tsc -w",
    "typings": "typings",
    "gulp": "gulp",
    "watch": "gulp watch",
    "ngc": "ngc"
  }
}
If you open your web application in the folder explorer, you can now see a node_modules folder with some external dependencies in there :
How to setup an Angular 2 and TypeScript project with Visual Studio 2017

Add Gulp

Add gulp.config.js

module.exports = function () {

    var base = {
        webroot: "./wwwroot/",
        node_modules: "./node_modules/"
    };

    var config = {
        /**
         * Files paths
         */
        angular: base.node_modules + "@angular/**/*.js",
        app: "App/**/*.*",
        appDest: base.webroot + "app",
        js: base.webroot + "js/*.js",
        jsDest: base.webroot + 'js',
        css: base.webroot + "css/*.css",
        cssDest: base.webroot + 'css',
        lib: base.webroot + "lib/",
        node_modules: base.node_modules,
        angularWebApi: base.node_modules + "angular2-in-memory-web-api/*.js",
        corejs: base.node_modules + "core-js/client/shim*.js",
        zonejs: base.node_modules + "zone.js/dist/zone*.js",
        reflectjs: base.node_modules + "reflect-metadata/Reflect*.js",
        systemjs: base.node_modules + "systemjs/dist/*.js",
        rxjs: base.node_modules + "rxjs/**/*.js",
        jasminejs: base.node_modules + "jasmine-core/lib/jasmine-core/*.*"
    };

    return config;
};
Add the gulp configuration file
How to setup an Angular 2 and TypeScript project with Visual Studio 2017

/*
This file is the main entry point for defining Gulp tasks and using Gulp plugins.
Click here to learn more. https://go.microsoft.com/fwlink/?LinkId=518007
*/

var gulp = require('gulp');

gulp.task('default', function () {
    // place code for your default task here
});

/// 
"use strict";

var gulp = require('gulp');
var config = require('./gulp.config')();
var cleanCSS = require('gulp-clean-css');
var clean = require('gulp-clean');
var rename = require('gulp-rename');
var $ = require('gulp-load-plugins')({ lazy: true });

gulp.task("clean:js", function (cb) {
    //return $.rimraf('wwwroot/js/*.min.js', cb);
    return gulp.src('wwwroot/js/*.min.js', { read: false }).pipe(clean());
});

gulp.task("clean:css", function (cb) {
    //return $.rimraf('wwwroot/css/*.min.css', cb);
    return gulp.src('wwwroot/css/*.min.css', { read: false }).pipe(clean());
});

gulp.task('minify:css', function () {
    return gulp.src(config.css)
        .pipe(cleanCSS())
        .pipe(rename({
            suffix: '.min'
        }))
        .pipe(gulp.dest(config.cssDest));
});

gulp.task("clean", ["clean:js", "clean:css"]);
gulp.task('minify', ['minify:css']);

gulp.task("copy:angular", function () {

    return gulp.src(config.angular,
        { base: config.node_modules + "@angular/" })
        .pipe(gulp.dest(config.lib + "@angular/"));
});

gulp.task("copy:angularWebApi", function () {
    return gulp.src(config.angularWebApi,
        { base: config.node_modules })
        .pipe(gulp.dest(config.lib));
});

gulp.task("copy:corejs", function () {
    return gulp.src(config.corejs,
        { base: config.node_modules })
        .pipe(gulp.dest(config.lib));
});

gulp.task("copy:zonejs", function () {
    return gulp.src(config.zonejs,
        { base: config.node_modules })
        .pipe(gulp.dest(config.lib));
});

gulp.task("copy:reflectjs", function () {
    return gulp.src(config.reflectjs,
        { base: config.node_modules })
        .pipe(gulp.dest(config.lib));
});

gulp.task("copy:systemjs", function () {
    return gulp.src(config.systemjs,
        { base: config.node_modules })
        .pipe(gulp.dest(config.lib));
});

gulp.task("copy:rxjs", function () {
    return gulp.src(config.rxjs,
        { base: config.node_modules })
        .pipe(gulp.dest(config.lib));
});

gulp.task("copy:app", function () {
    return gulp.src(config.app)
        .pipe(gulp.dest(config.appDest));
});

gulp.task("copy:jasmine", function () {
    return gulp.src(config.jasminejs,
        { base: config.node_modules + "jasmine-core/lib" })
        .pipe(gulp.dest(config.lib));
});

gulp.task("dependencies", [
    "copy:angular",
    "copy:angularWebApi",
    "copy:corejs",
    "copy:zonejs",
    "copy:reflectjs",
    "copy:systemjs",
    "copy:rxjs",
    "copy:jasmine",
    "copy:app"
]);

gulp.task("watch", function () {
    return $.watch(config.app)
        .pipe(gulp.dest(config.appDest));
});

gulp.task("default", ["clean", 'minify', "dependencies"]);
You can see now a task "default" in the task explorator
How to setup an Angular 2 and TypeScript project with Visual Studio 2017
How to setup an Angular 2 and TypeScript project with Visual Studio 2017
You can see that the dependencies has been added in the lib folder.
How to setup an Angular 2 and TypeScript project with Visual Studio 2017

Add Bower

Add bower to add jquery and boostrap dependencies
How to setup an Angular 2 and TypeScript project with Visual Studio 2017

Create TypeScript app files

Create the main file to bootstrap your application

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

const platform = platformBrowserDynamic();

platform.bootstrapModule(AppModule);
Add app.module.ts

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

import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { AppRoutingModule } from './app-routing.module';

@NgModule({
    imports: [
        BrowserModule,
        HttpModule,
        AppRoutingModule
    ],
    declarations: [
        AppComponent,
        HomeComponent
    ],
    bootstrap: [AppComponent],
    providers: [
    ]
})
export class AppModule { }
Add app.component.ts

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

@Component({
    selector: 'no404-bo-app',
    template: `
        
`,
    providers: []
})
export class AppComponent implements OnInit {

    constructor() {
        console.log('AppComponent -> constructor');
    }

    ngOnInit() {
        console.log('AppComponent -> ngOnInit');
    }
}
Create the routing module (app-routing.module.ts)

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './home/home.component';

export const routes: Routes = [
    { path: '', redirectTo: 'home', pathMatch: 'full' },
    { path: 'home', component: HomeComponent }
];

@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule]
})
export class AppRoutingModule { }
And add the home component

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

@Component({
    selector: 'home',
    template: `
        

Home

Hello you !
`
}) export class HomeComponent implements OnInit { constructor() { console.log('HomeComponent -> constructor'); } ngOnInit() { console.log('HomeComponent -> ngOnInit'); } }
How to setup an Angular 2 and TypeScript project with Visual Studio 2017
If you build your solution, you can see that your outpout app folder has been populated with some javascript files generated by your TypeScript files.
How to setup an Angular 2 and TypeScript project with Visual Studio 2017
If you launch your website, you will have something like this :
How to setup an Angular 2 and TypeScript project with Visual Studio 2017
No trace in the console and not the content in our typescript templates. Why ? Cause we have to tell our website startup that we want to load our typescript application.

Configure your web app to dispay your angular application

Check if your application is targeting the .NETCoreApp framework, version 1.1, if not update it.
How to setup an Angular 2 and TypeScript project with Visual Studio 2017
Check if the Nuget dependencies are targeting the last version, if not update them all.
How to setup an Angular 2 and TypeScript project with Visual Studio 2017
Add the Nuget dependencies you need :
  • Microsoft.AspNetCore.Mvc
  • Microsoft.AspNetCore.StaticFiles
  • Microsoft.Extensions.Logging.Debug
  • Microsoft.Extensions.Configuration.Json
Microsoft.AspNetCore.StaticFiles is a middleware for handling requests for file system resources including files and directories that enable your application to serve HTML and javascript files, indispensable elements of an Angular application.
For more information about Microsoft.AspNetCore.StaticFiles, you can see :
How to setup an Angular 2 and TypeScript project with Visual Studio 2017
Once you have added the Microsoft.AspNetCore.StaticFiles package, you have to enable your app to serve static files. It occurs in the Configure method in the startup class, using app.UseStaticFiles():.

public void ConfigureServices(IServiceCollection services)
{
    services
               .AddMvc()
               .AddJsonOptions(options => options.SerializerSettings.ContractResolver =
                   new DefaultContractResolver());
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    app.UseCors(
        builder => builder.AllowAnyOrigin()
            .AllowAnyHeader()
            .AllowAnyMethod()
            .AllowCredentials())
        .UseStaticFiles();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

Add the Home controller with the view

Add HomeController and Index.cshtml in the home folder of the Views.
Add systemjs.config.js javascript file in your js folder of the wwwroot folder.

(function (global) {
    System.config({
        paths: {
            'npm:': 'lib/'
        },
        map: {
            app: 'app',
            '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
            '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
            '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
            '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
            '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
            '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
            '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
            '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
            'rxjs': 'npm:rxjs',
            'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
        },
        packages: {
            app: {
                main: './main.js',
                defaultExtension: 'js'
            },
            rxjs: {
                defaultExtension: 'js'
            },
            'angular2-in-memory-web-api': {
                main: './index.js',
                defaultExtension: 'js'
            }
        }
    });
})(this);
Set up the content of your Index.cshtml view to load the ui dependencies your need, and load your Angular application.


<html>
<head>
    <base href="/">
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="~/css/site.css" />

    <script src="~/lib/jquery/dist/jquery.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>

    <script src="~/lib/core-js/client/shim.js"></script>
    <script src="~/lib/zone.js/dist/zone.js"></script>
    <script src="~/lib/reflect-metadata/Reflect.js"></script>
    <script src="~/lib/systemjs/dist/system.src.js"></script>

    <script src="~/js/systemjs.config.js"></script>
    <script>
      System.import('app').catch(function(err){ console.error(err); });
    </script>
</head>
<body>
    <div class="container">
        <no404-bo-app>Loading...</no404-bo-app>
    </div>
</body>
</html>

And it's work !

If you launch your application now, you can see that all is working and your Angular 2 application is correctly loaded.
How to setup an Angular 2 and TypeScript project with Visual Studio 2017
You can now implement your Angular 2 application to do what you have to do. Enjoy :)



PS: If you see a strange C folder appearing in your solution, follow this tutorial : Update ASP.NET Core web application to .NETCoreApp1.1 causes a project loading failure
How to setup an Angular 2 and TypeScript project with Visual Studio 2017
February 11, 2017
  • ASP.NET Core
  • Angular
  • Angular2
  • TypeScript
  • NPM
  • Node.js
  • MVC