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:
And the second is gulpfile.js:
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:
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.
Leave a Reply