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.

Advertisements
Using Gulp in an ASP.NET 4.5 application

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s