Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Javascript

How to Automate ASP.NET Custom Controls with the Gulp JavaScript Task Runner

5.00/5 (1 vote)
2 Oct 2014Ms-PL4 min read 9.1K  
Are you building ASP.NET web applications? Do you Gulp? In this article, I introduce how to use Gulp with Visual Studio. The sample walks through automating static file packaging for custom ASP.NET controls.

gulp-2x.png

Here I am, writing a module for my next Pluralsight course and I ran into an interesting problem. When I write a custom ASP.NET control, I now have lots of JavaScript and CSS libraries that I want to ship with it. With the introduction of the Task Runner Explorer in Visual Studio, I decided to try my hand at writing a Gulp script that will combine and compress these static resources inside of my class library project.

Introducing Gulp for the ASP.NET Developer

Gulp is another task runner for use with NodeJS, similar to Grunt. Unlike Grunt, Gulp runs based on a JavaScript file of instructions and can be run in an asynchronous manner. This leads to Gulp being a bit easier to read as a series of functions that will run faster than the Grunt JSON configuration file.

To get started with Gulp and Visual Studio:

  1. Install NodeJS from www.nodejs.org
  2. Install Gulp with the NPM package manager as follows:
    npm install gulp -g

    This will install Gulp globally and make the gulp command-line executable available.

  3. Create a package.json file in the root of your project. This can be a file that contains just a pair of curly braces.
  4. Configure gulp locally to the project by running the following script on the command line at the project root folder:
    npm install gulp --save-dev
  5. Install a handful of gulp plugins to manage the concatenation, renaming, minifying and notification processes:
    npm install gulp-minify-css gulp-concat gulp-uglify gulp-notify gulp-rename --save-dev

With those commands issued, we're ready to build our gulpfile.js to contain the instructions for how to automate working with our static resources.

Create a file called gulpfile.js on the root of the project. This file should be excluded from the project. Begin by defining a series of variables using gulp's built-in require commands:

JavaScript
var gulp = require('gulp'),
  concat = require('gulp-concat'),
  minifycss = require('gulp-minify-css'),
  rename = require('gulp-rename'),
  notify = require('gulp-notify'),
  uglify = require('gulp-uglify');

Next, we can define a simple gulp task to minify the bootstrap.css file that is in our project:

JavaScript
gulp.task('css', function() {

  return gulp.src('css/bootstrap.css')
    .pipe(rename('mycontrols.min.css'))
    .pipe(minifycss())
    .pipe(gulp.dest('css'))
    .pipe(notify({message: 'Styles minified'}));

});

The name of the task is "css" and it will trigger a function. The function returns the result of operations on the css/bootstrap.css file. The file is piped from one operation to the next with the pipe method. First, the file is renamed to mycontrols,min.css so that the file matches the "mycontrols" project name. Next, the contents of the CSS file are minified with the minifycss command and then piped to the CSS folder using the gulp.dest method. Finally, a notification is triggered with the notify method and the message text specified.

The JavaScript processing is similar:

JavaScript
gulp.task('js', function() {
  
  return gulp.src(['scripts/jquery-1.10.2.js','scripts/respond.js','scripts/bootstrap.js'])
    .pipe(concat('mycontrols.js'))
    .pipe(gulp.dest('scripts'))
    .pipe(rename({suffix: '.min'}))
    .pipe(uglify())
    .pipe(gulp.dest('scripts'))
    .pipe(notify({message: 'Scripts merged and minified'}));

});

This time, I am passing an array of files in to be processed. The collections are concatenated together with the concat method into the mycontrols.js file and written into the scripts folder with another gulp.dest method. The filename is renamed with a suffix of .min and sent into the uglify processor for minification. The results of the uglification are written back to the scripts folder and a notification is triggered with an appropriate message.

Finally, I wrote a default task to call the JS and CSS tasks. I called this task default:

JavaScript
gulp.task('default', ['js','css'], function() {});

The second argument in this method call is the collection of dependent tasks that should be called before the function is executed. In this way, the js and css tasks are called asynchronously.

Automating Gulp with Task Runner Explorer

Image 2

With the Task Runner Explorer extension in Visual Studio, I can connect any and all of these tasks to various steps in the build process. In my case, I right-clicked on the 'default' task and chose to bind it to the 'Before Build' run time.

Now, every time I build my MyControls project, the gulp default task will run and deliver appropriate CSS and JS files for my controls to use.

Custom Control Project Considerations

Importantly, for this project, I marked my gulpfile, package.json, and all of my original CSS and JS files as Build Action None and Do not copy to output directory. I did mark the new mycontrols.min.js and mycontrols.min.css as Embedded Resources so that they would be delivered inside of the DLL I will distribute with my controls.

Configuration for files to exclude from my DLL

Configuration for files to exclude from my DLL

Configuration for files to include in my DLL

Configuration for files to include in my DLL

Summary

The new Task Runner Explorer combined with the NodeJS command line interface and Gulp have made automating packaging assets for my custom controls much easier than previously. Now, visitors to my applications will download one script file and one CSS file for my controls. This will provide a faster and easier experience for my visitors and my developers that use my custom ASP.NET controls.

Image 5

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)