Upgrade an Angular 2 application to Angular 4

One years ago I wrote a series of posts about Angular 2 and how we can develop a base application with this new framework.

The time is gone and during this period many releases came; the last Angular 4 version is 4.4.6 and a new stable version of the framework has been released in version 5.

So I decided to upgrade this base application to the version 4 and check what are the main differences.

I choose to not use angular-cli but to upgrade the application manually, so I didn’t have to create a new project.

In the upgrade process I met some changes that I describe below.

Packages

The first thing that I have done was upgrade the package.json file of my old application.

{
"name": "angular4.web",
"version": "0.0.0",
"license": "MIT",
"private": true,
"dependencies": {
"@angular/animations": "^4.4.6",
"@angular/common": "^4.4.6",
"@angular/compiler": "^4.4.6",
"@angular/core": "^4.4.6",
"@angular/forms": "^4.4.6",
"@angular/http": "^4.4.6",
"@angular/platform-browser": "^4.4.6",
"@angular/platform-browser-dynamic": "^4.4.6",
"@angular/router": "^4.4.6",
.....
}
.....
}

With “npm install” command I have upgraded the angular packages without particular problems and the source code of the application was compliant to the new framework version.

The only problem that I have encountered was on the translate module, that is moved from ng2-translate to ngx-translate.

Translate factory

In the package.json I have replaced the new package like this:


{
"dependencies": {
.....
"@ngx-translate/core": "^8.0.0",
.....
}
}

Then I replaced all the modules that depended on it with the new reference:


import { TranslateModule } from '@ngx-translate/core';

.....

Fortunately, the service and methods of the new packages were the same of ng2-translate package, so I didn’t had to change the code.

ngIf directive refactoring

Once the application worked I tried to leverage some new features of Angular 4.

In detail, I used the ngIf directive in order to simplify the html code of a couple of page.

For example, the invoice.component.html file, that had this structure, now looks like this:

<div *ngIf="!edit; else editBlock">
<input type="button" class="btn btn-primary" value="New" (click)="New()" />
<table class="table table-striped">
<thead>
<tr>
<th>
{{ "NUMBER" | translate }}</th>
<th>
{{ "CUSTOMER" | translate }}</th>
<th>
{{ "EMISSIONDATE" | translate }}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let invoice of (invoices | searchInvoices: searchService.searchText)" (click)="Edit(invoice)">
<td>
{{invoice.Number}}/{{invoice.Year}}</td>
<td>
{{invoice.Customer.Name}}</td>
<td>
{{invoice.EmissionDate | date: "dd/MM/yyyy"}}</td>
</tr>
</tbody>
</table>
</div>
<ng-template #editBlock>
<app-invoice-detail *ngIf="invoice" [invoice]="invoice" [isNew]="newInvoice" [validationEnabled]="invoiceValidationEnabled"
(onClosed)="onClosed($event)" (onDeleted)="onDeleted($event)"></app-invoice-detail>
</ng-template>

I removed the hidden attribute from the original page and I used the ngIf directive to manage the visibility of the detail block.

You can find the Angular 4 application here.

Advertisements
Upgrade an Angular 2 application to Angular 4

Typescript checking with TSLint

TSLint is a linter for Typescript, then a program that analyse our code to find potential errors and make the code more readable.

The very nice feature is that TSLint has a separate json file, named tslint.json, to configure the analisys process and allow us to setup the rules; we need to put this file in the root of the project and tslint will use that to read the settings.

Once defined the configuration, we’ll embed this in a task runner process like Gulp and we’ll have a complete process to fix all the typescript projects.

TSLint installation

First of all, we need to install the TSLint npm package and the Gulp TSlint plugin:

npm install tslint –save-dev

npm install gulp-tslint –save-dev

These packages will be added to the package.json file in the root of the project.

TSLint configuration

You need to add tslint.json file in the root of the project and compile that; there are many options that you can specify, the nomenclature is clear and it’s very easy to understand what a specific option means.

After some test, this is the configuration file applied:

{
"rules": {
"align": [ true, "arguments", "parameters", "statements" ],
"class-name": true,
"comment-format": [ true, "check-lowercase", "check-space" ],
"curly": true,
"eofline": true,
"indent": [ true, "spaces" ],
"interface-name": [ true, "always-prefix" ],
"jsdoc-format": true,
"label-position": true,
"label-undefined": true,
"member-access": true,
"member-ordering": [
true,
{
"order": "fields-first"
}
],
"no-any": false,
"no-arg": true,
"no-conditional-assignment": true,
"no-consecutive-blank-lines": true,
"no-construct": true,
"no-constructor-vars": true,
"no-debugger": true,
"no-duplicate-key": true,
"no-duplicate-variable": true,
"no-empty": true,
"no-eval": true,
"no-inferrable-types": false,
"no-internal-module": true,
"no-require-imports": true,
"no-shadowed-variable": true,
"no-string-literal": true,
"no-switch-case-fall-through": true,
"no-trailing-whitespace": true,
"no-unreachable": true,
"no-unused-expression": true,
"no-unused-variable": true,
"no-use-before-declare": true,
"no-var-keyword": true,
"no-var-requires": true,
"one-line": [ true, "check-catch", "check-else", "check-finally", "check-open-brace", "check-whitespace" ],
"quotemark": [ true, "double" ],
"radix": true,
"semicolon": [ true, "always" ],
"switch-default": true,
"triple-equals": true,
"typedef": [ true, "arrow-parameter", "call-signature", "member-variable-declaration", "parameter", "property-declaration", "variable-declaration" ],
"use-strict": [ true, "check-function", "check-module" ],
"variable-name": [ true, "check-format", "allow-leading-underscore", "ban-keywords" ],
"whitespace": [ true, "check-branch", "check-decl", "check-operator", "check-separator", "check-type" ]
}
}

TSLint gulp task

The Gulp plugin need to be added to the gulpfile.js file:


'use strict';

var gulp = require('gulp'),
...
tslint = require('gulp-tslint')

gulp.task('tslint', function () {
gulp.src(config.ts)
.pipe(tslint({
formatter: 'verbose'
}))
.pipe(tslint.report({
emitError: true,
sort: true,
fullPath: true,
reportLimit: 10
}))
});

We have some options that we can specify for the report, the reportLimit is very useful when you execute the task for the first time and the report is too long.

Now, you can execute the task with the command:

gulp tslint

In the console the analisys report will be showed:

tslint_report

You can find the project here.

 

 

 

 

 

 

Typescript checking with TSLint

Bootstrapping an Angular 2 application

In an Angular 2 application we have different options to load application and modules, and one of these is SystemJS.

This is an open source project that give us the ability to load bunch of modules and define for each one the corresponding default main module.

Therefore you can use this library to define a default main module for an Angular 2 application; the first step is install this with npm, by adding as a dependency in the package.json file of the project:


{
 ...
 },
 "license": "ISC",
 "dependencies": {
 ...
 "systemjs": "0.19.27",
 ...
 },
 "devDependencies": {
 ...
 }
}

This library allows you to configure you application startup and defaults by using a specific json file.

The file that we need to create is called systemjs.config.js:

(function (global) {
 var map = {
 'app': 'app',
 ...
 };
 var packages = {
 'app': { main: 'main.js', defaultExtension: 'js' },
 ...
 };
var config = {
 map: map,
 packages: packages
 };
 System.config(config);
})(this);

Notice that one of the packages property is app, that is our app selector, and for that we specify the main property, that is the default loader; you can also use this file to configure other stuff, such as bundling or other default main modules.

The last step is create the loader file, that we can call, for example, Main.ts:

import { bootstrap } from '@angular/platform-browser-dynamic';
import { AppComponent } from './App.Component';
bootstrap(AppComponent);

With the last row, we will load as default the AppComponent, that is the main component of our app.

Finally, this is the App.Component.ts file:

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

@Component({
 selector: 'app',
 templateUrl: 'app/views/app.html'
})

export class AppComponent {
 title: string = 'New App';
}

The selector property of the component is the value that we have assigned in the fourth row of the systemjs.config.js above.

 

Bootstrapping an Angular 2 application

Add Bower in an ASP.NET 4.5 application

Bower is packager manager that allow you to manage the client packages of your application and it can be easily integrated with in a deploy workflow with a task runner like Gulp.

In this example, the sample application is an ASP.NET application with some NuGet packages installed and using Gulp to automate the deploy workflow.

With Bower you can manage packages like AngularJS, Boostrap, JQuery and so on; it’s a front-end package manager and it can be installed with npm (Node.js Package manager) :

npm install bower -g

In order to using Bower in an ASP.NET application, the first step is adding the bower.json file:

bower

Bower install the packages in the path defined in the file .bowerrc and you can change it:

{
"directory": "bower_components"
}

Now you can using Bower to install the client packages which the application needs.

Once of the packages installed with NuGet on the existing application is AngularJS; it can be installed with Bower:

bower install angular –save

With the option –save, the bower.json file will be updated:

{
"name": "angular-signalr",
"private": true,
"main": [
""
],
"dependencies": {
"angular": "~1.5.5",
}
}

You can do the same operation for the other packages of the application; they will be installed in the bower_components path and new rows will be added in the bower.json file:

{
"name": "angular-signalr",
"private": true,
"main": [
""
],
"dependencies": {
"angular": "~1.5.5",
"angular-bootstrap": "angular-ui-bootstrap-bower#~1.3.2",
"angular-ui-router": "~0.2.18",
"AngularJS-Toaster": "aangular-toaster#~0.4.11",
"angular-loading-bar": "~0.9.0",
"angular-animate": "~1.5.5",
"angular-resource": "~1.5.5",
"bootstrap": "~3.3.6",
"jquery-ui": "~1.11.4",
"jquery": "~2.2.3",
"signalr": "~2.2.0",
"q": "1.0.1"
}
}

Now what we need to do is automate the workflow and inject these packages in the index page; you can do that with two Gulp plugins:

npm install –save-dev gulp-bower

npm install –save wiredep

You can find exhaustive documentation about these two plugins on the npm site.

The next step is adding the dependencies in the gulpfile.js of the application and creating the new task:

'use strict';

var gulp = require('gulp'),
bower = require('gulp-bower'),
wiredep = require('wiredep').stream

gulp.task('bower', function () {
return bower();
});

gulp.task('wiredep', ['bower'], function () {
var source = gulp.src('./' + config.indexDev);

return source.pipe(wiredep({}))
.pipe(gulp.dest('.'));
});

The main html file need to be changed, in order to make wiredep working:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>Angular SignalR Application</title>

  <!-- build:css Content/lib.min.css -->
  <!-- bower:css  -->
  <!-- endbower -->
  <!-- endbuild -->

  <!-- build:js Scripts/lib.min.js -->
  <!-- bower:js  -->
  <!-- endbower -->
  <!-- endbuild -->
</head>
<body ng-app="angularSignalR">
</body>
</html>

In the bower.json file you need also specify the main application modules:

{
"name": "angular-signalr",
"private": true,
"main": [
""
],
"dependencies": {
"angular": "~1.5.5",
"angular-bootstrap": "angular-ui-bootstrap-bower#~1.3.2",
"angular-ui-router": "~0.2.18",
"AngularJS-Toaster": "aangular-toaster#~0.4.11",
"angular-loading-bar": "~0.9.0",
"angular-animate": "~1.5.5",
"angular-resource": "~1.5.5",
"bootstrap": "~3.3.6",
"jquery-ui": "~1.11.4",
"jquery": "~2.2.3",
"signalr": "~2.2.0",
"q": "1.0.1"
},
"overrides": {
"angular": {
"main": [
"angular.js"
]
},
"angular-bootstrap": {
"main": [
"ui-bootstrap-csp.css",
"ui-bootstrap.js",
"ui-bootstrap-tpls.js"
]
},
"angular-ui-router": {
"main": [
"release/angular-ui-router.js"
]
},
"AngularJS-Toaster": {
"main": [
"toaster.css",
"toaster.js"
]
},
"angular-loading-bar": {
"main": [
"src/loading-bar.css",
"src/loading-bar.js"
]
},
"angular-animate": {
"main": [
"angular-animate.js"
]
},
"angular-resource": {
"main": [
"angular-resource.js"
]
},
"bootstrap": {
"main": [
"dist/css/bootstrap.css",
"dist/js/bootstrap.js"
]
},
"jquery": {
"main": [
"dist/jquery.js"
]
},
"jquery-ui": {
"main": [
"jquery-ui.js"
]
},
"q": {
"main": [
"q.js"
]
},
"signalr": {
"main": [
"jquery.signalR.js"
]
}
}
}

Now the configuration is completed and you can run the gulp tasks; once verified that the application works correctly, you can proceed with uninstalling the NuGet packages managed with bower; for example unistall AngularJS:

uninstall package AngularJS

You can find the project here.

 

 

 

 

Add Bower in an ASP.NET 4.5 application

Angular implicit annotation with Gulp

As you know, AngularJS provide the management of the module dependencies through the dependency injection.

In order to be able to manage these dependencies, Angular allows specific annotations that the developers can use to define their modules.

Dependency Annotation

For example, in an Angular application written with Typescript, the dependencies can be inject in the run method with this syntax:


AngularSignalR.module.config(['$stateProvider', '$urlRouterProvider', ($stateProvider, $urlRouterProvider) =&gt; {
$urlRouterProvider.otherwise(&quot;/orders&quot;);

$stateProvider
.state('Orders', {
url: '/orders',
templateUrl: '/app/views/orders.html',
controller: 'OrdersController as vm'
});
}]);

This is the most used syntax and is called Inline Array Annotation; another option is using the $inject property:


module AngularSignalRApp.Controllers {

export class ModalsController {
private modalInstance: ng.ui.bootstrap.IModalServiceInstance;

public static $inject = ['$uibModalInstance'];

constructor(modalInstance: ng.ui.bootstrap.IModalServiceInstance) {
this.modalInstance = modalInstance;
}

}

AngularSignalR.module.controller('ModalsController', ModalsController);
}

The order specified in the $inject property must match the controller arguments; this is the Property Annotation.

The last options allow to leave out the manual injection of the parameters and assuming that the parameter names are the names of the dependencies; this is called implicit annotation:


module AngularSignalRApp.Controllers {

export class ModalsController {
private modalInstance: ng.ui.bootstrap.IModalServiceInstance;

constructor($uibModalInstance: ng.ui.bootstrap.IModalServiceInstance) {
this.modalInstance = $uibModalInstance;
}
}

AngularSignalR.module.controller('ModalsController', ModalsController);
}

Gulp plugin

Unfortunately, the implicit annotation doesn’t work with the minification process due to the rename of the parameters.

You can work around this problem by using the Gulp plugin gulp-ng-annotate; first of all, you need to install it as a project dev dependency:

npm install gulp-ng-annotate –save-dev

And add it in the gulpfile.js of the web application:


var gulp = require('gulp'),
ngAnnotate = require('gulp-ng-annotate')

Now you need to add the plugin inside the task that execute the minification process.

In this application it’s used gulp-useref, and you need to add the plugin before the uglify process:


gulp.task('useref', ['inject'], function () {
var source = gulp.src(config.indexDev);
var jsFilter = filter('**/*.js', { restore: true });
var cssFilter = filter('**/*.css', { restore: true });

return source
.pipe(useref())
.pipe(cssFilter)
.pipe(cleanCss())
.pipe(cssFilter.restore)
.pipe(jsFilter)
.pipe(ngAnnotate())
.pipe(uglify())
.pipe(jsFilter.restore)
.pipe(rev())
.pipe(revReplace())
.pipe(gulp.dest(config.dist));
});

With this operations, we can using implicit annotation without encountering problems after minification process.

You can find the project here.

 

 

Angular implicit annotation with Gulp

Compile Typescript with Gulp

Gulp is a build tools that can be used, among other things, as a Typescript compiler and sourcemaps generator.
As you know, Typescript is a superset of Javascript which offer you static typing, classes, interfaces;  Sourcemaps are additional files that allow you to debug, from the browser debugger, source files (typescript files) instead of Javascript files.

Visual Studio Typescript build

Every time you save a Typescript file from Visual Studio, you can see that the associated js and maps files are updated; this option can be manage in the project settings:

compileOnSave
And the same event occur every time the project is built; to disable this feature, there is an option in the typescript property file:

typescriptProperty

Once you changed this setting for all typescript files, the Visual Studio Typescript compiling is disabled and the typescript files will no longer been updated.

Tasks

In order to compile Typescript files with Gulp, you need to install these plugins:

npm install gulp-typescript –save

npm install gulp-sourcemaps –save

The first plugin is to compile Typescript and generate Javascript files; the second one is the plugin for Sourcemaps.

Once installed you need to include them in the gulpfile.js:

var gulp = require('gulp'),
ts = require('gulp-typescript'),
sourcemaps = require('gulp-sourcemaps')

The next step is to write the Gulp task:


var tsProject = ts.createProject({
target: 'ES5',
module: 'CommonJS',
noExternalResolve: false,
noEmitOnErrors: true,
noImplicitAny: true
});

gulp.task('typescript', function () {
var tsResult = gulp.src(config.ts)
.pipe(sourcemaps.init())
.pipe(ts(tsProject));

return tsResult.js
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(config.jsBasePath));
});

There are several options for the Typescript compiler; one of that is the external module system, which in case of Node.js is CommonJS.

Another option is noImplicitAny that force the developer to declare the type for any object used in the Typescript file.

Now you can run the task and see the files in the app folder:

files

The last step is enable build every time a typescript file is saved; in order to do that, you can use gulp watch:

gulp.task('watchTypescript', ['typescript'], function () {
gulp.watch(config.ts, ['typescript']);
});

You can find the project here.

Compile Typescript with Gulp

Using Gulp in an ASP.NET 4.5 application

The use of a task runner in an ASP.NET application provide a series of advantages about concatenating and minifying CSS and Javascript application files and offers a real and valid alternative to the ASP.NET optimization framework.

One of the most recent task runner is Gulp, that using code over configuration for more readable syntax and node streams for better performances at build time.

Web application

If the referenced project is an ASP.NET 4.5 application, the first steps are adding two files in the project; the first is package.json:

npm

And the second is gulpfile.js:

gulp

Node.js installation

The primary step is to install Node.js, the server-side javascript runtime which will be used by Gulp.

Node.js installation is very simple and offer a GUI to do that; once installed, the next step is the Gulp installation.

Gulp

Npm is the package manager of Node.js and it can be used to install Gulp; a package could be installed locally (in the application folder under node_modules) or globally (the folder specified in the NODE_PATH environment variable); with this second option the package could be used later for other applications.

Therefore, Gulp should be installed globally; opening a command prompt you can perform the installation with the option g (global):

npm install gulp -g

If the project is shared with other developers, is recommended to add gulp as a development dependency of the project; in order to do that, run this command:

npm install gulp –save-dev

Once installed the package.json file will be changed with the new reference of Gulp.

{
"version": "1.0.0",
"name": "ANGULAR-SIGNALR",
"devDependencies": {
"gulp": "^3.9.1"
}
}

Inject

With Gulp inject plugin is possible to manage the js/css references in the application main page.

For example, you can use this plugin to inject javascript files of an angular application in the main page.

In order to do that, you need to first install the plugin:

npm install –save-dev gulp-inject

Than you need to include the plugin in the gulpfile.js and write the task:

'use strict';

var gulp = require('gulp'),
inject = require('gulp-inject')

var config = {
js: 'App/**/*.js',
dist: './dist',
indexDev: 'index.dev.html'
}

//Inject
gulp.task('inject', function (cb) {
var target = gulp.src(config.indexDev);
var sources = gulp.src([config.js]);

return target.pipe(inject(sources))
.pipe(gulp.dest('.'));
});
// End inject

And in the index.dev.html body add the injection placeholders:

<body ng-app="angularSignalR">
<!-- inject:js -->
<script src="/App/App.js"></script>
  <script src="/App/Commons.js"></script>
<script src="/App/Controllers/ModalsController.js"></script>
  <script src="/App/Controllers/OrdersController.js"></script>
<script src="/App/Directives/DecimalNumberValidationDirective.js"></script>
  <script src="/App/Services/NotificationsService.js"></script>
<script src="/App/Services/OrdersService.js"></script>
  <script src="/App/Models/Order.js"></script>
<!-- endinject -->
</body>

Once inject task will be executed, it’ll retrive all javascript file from config.js path and inject them into the html page, between the corrispondent placeholders.

Minification

This is the process to minify vendor css, javascript vendor libraries and javascript application files.

You need to install some plugins:

npm install gulp-clean-css –save-dev

npm install gulp-useref –save-dev

npm install gulp-if –save-dev

npm install gulp-rename –save-dev

Add the new task to the gulpfile.js:

//Useref
gulp.task('useref', ['inject'], function () {
var source = gulp.src('index.dev.html');

return source
.pipe(useref())
.pipe(gulpif('*.css', cleanCss()))
.pipe(gulpif('*.js', uglify()))
.pipe(gulp.dest(config.dist));
});
//End Useref

Add the useref build placeholders in the index.dev.html body:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Angular SignalR Application</title>

<!-- build:css Content/lib.min.css -->
	<link href="/Content/bootstrap.css" rel="stylesheet" />
	<link href="/Content/ui-bootstrap-csp.css" rel="stylesheet" />
	<link href="/Content/loading-bar.css" rel="stylesheet" />
	<link href="/Content/toaster.css" rel="stylesheet" />
<!-- endbuild -->

<!-- build:js Scripts/lib.min.js -->
<script src="/Scripts/jquery-2.2.1.js"></script>
  <script src="/Scripts/jquery.signalR-2.2.0.js"></script>
<script src="/Scripts/bootstrap.js"></script>
  <script src="/Scripts/q.js"></script>
<script src="/Scripts/angular.js"></script>
  <script src="/Scripts/angular-resource.js"></script>
<script src="/Scripts/angular-animate.js"></script>
  <script src="/Scripts/angular-ui-router.js"></script>
<script src="/Scripts/angular-ui/ui-bootstrap.js"></script>
  <script src="/Scripts/angular-ui/ui-bootstrap-tpls.js"></script>
<script src="/Scripts/loading-bar.js"></script>
  <script src="/Scripts/toaster.js"></script>
<!-- endbuild -->
</head>
<body ng-app="angularSignalR">
<toaster-container></toaster-container>

<section class="container">
<div ui-view=""></div>
</section>

<!-- build:js Scripts/app.min.js -->
<!-- inject:js -->
<script src="/App/App.js"></script>
  <script src="/App/Commons.js"></script>
<script src="/App/Controllers/ModalsController.js"></script>
  <script src="/App/Controllers/OrdersController.js"></script>
<script src="/App/Directives/DecimalNumberValidationDirective.js"></script>
  <script src="/App/Services/NotificationsService.js"></script>
<script src="/App/Services/OrdersService.js"></script>
  <script src="/App/Models/Order.js"></script>
<!-- endinject -->
<!-- endbuild -->
</body>
</html>

As you can see, useref is a very powerful plugin; combining that with clean-css and uglify (plugin for minification) permit to generate minified files with few lines of code.

The final index.html page will be generated in dist subdirectory:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Angular SignalR Application</title>

	<link rel="stylesheet" href="Content/lib.min.css">

<script src="Scripts/lib.min.js"></script>
</head>
<body ng-app="angularSignalR">
  <toaster-container></toaster-container>

  <section class="container">

<div ui-view=""></div>

  </section>

  <script src="Scripts/app.min.js"></script>
</body>
</html>

The useref palceholders has been replaced with minified files.

Move result files

The index.html page generated in the dist directory have to be moved in the root directory and the css/js file in the Content/Scripts folders.

You need to install two plugins:

npm install gulp-rename –save-dev

npm install gulp del –save-dev

In order to moving the files, implementation of different tasks is needed:

//Move/Rename
gulp.task('renameIndexDist', ['inject'], function (cb) {
return gulp.src(config.dist + '/' + config.indexDev)
.pipe(rename({
basename: 'index'
}))
.pipe(gulp.dest(config.dist));
});

gulp.task('removeIndexDist', ['renameIndexDist'], function (cb) {
return del([config.dist + '/' + config.indexDev], { force: true });
});

gulp.task('copyDist', ['removeIndexDist'], function () {
return gulp.src(config.dist + '/**/*.*')
.pipe(gulp.dest('.'));
});

gulp.task('moveDist', ['copyDist'], function () {
return del([config.dist], { force: true });
});

gulp.task('renameIndexDev', ['inject'], function () {
return gulp.src('./' + config.indexDev)
.pipe(rename({
basename: 'index'
}))
.pipe(gulp.dest('.'));
});
//End Move/Rename

The task is composed of different subtasks; the first is renameIndexDist, that rename dist/index.dev.html file to dist/index.html; removeIndexDist remove the old index file, than copyDist move the files and modeDist delete dist directory as final step.

RenameIndexDev is a task that will be called in debug mode, when dist directory is not generated and index.dev.html is not minified.

Build configuration

The minification of javascript files is essentially in a release configuration, but not in debug mode, where unminify files are more useful for debugging.

To do that, it’s necessary to distiguish the configuration in the gulpfile.js and execute the correct tasks.

By open the project settings in Visual Studio, it’s possible to define a post-build event command:

build

In the gulpfile.js, add the environment parameter check:

gulp.task('scripts', function () {
if (process.env.NODE_ENV == 'Debug') {
gulp.start('inject', 'renameIndexDev');
}
else {
gulp.start('inject', 'useref', 'moveDist');
}
});

You can find the project here.

Using Gulp in an ASP.NET 4.5 application