Asset Pipeline has become popular thanks to Ruby on Rails which implements it nicely out of the box. In this post I will explain what an asset pipeline is, how you can easily implement it without using Ruby on Rails and why you should consider using it in building a webapp.

What is Asset Pipeline?

Asset Pipeline is the name given to the way we serve static files to web applications. An asset pipeline can do many things to our files before they are served. Below are the most important and most used actions we can perform on static files.

Javascript

  • Concatenate many JS files into one;
  • Compress;
  • Uglify;
  • Minify;
  • Compile CoffeeScript into JS.

Stylesheets:

  • Compile SASS into CSS files;
  • Concatenate files;
  • Minify;

Images:

  • Optimize;

There are many ways to implement the tasks above. You could perform these tasks manually whenever you change any file (which is not a good idea) or you can use task runners to automate them, such as Grunt or Gulp.

Implementing an Asset Pipeline in Gulp JS

As I mentioned above, Gulp is a task runner and it can automate many things for you. In this post I’m going to use it to automate the necessary tasks to build an asset pipeline.

The complete code can be found here. In order to run it in your machine I recommend you to git clone the project and install the dependencies by running:

$ npm install

* Assuming you have node.js installed

Now let’s take a look at gulpfile.js. This is the most important file in Gulp, where everything is defined.

We start off by declaring all the plugins we’re going to use in our tasks. There are plenty of plugins available for almost any task you need.

var gulp = require('gulp'),  
    coffee = require('gulp-coffee'),
    concat = require('gulp-concat'),
    uglify = require('gulp-uglify'),
    clean = require('gulp-clean'),
    sass = require('gulp-sass'),
    imagemin = require('gulp-imagemin');

Next we’ll declare the paths where our scripts, stylesheets and images reside.

var paths = {  
  scripts: ['app/scripts/**/*.coffee', 'app/scripts/**/*.js'],
  styles:  ['app/styles/**/*.scss', 'app/styles/**/*.css'],
  images:  ['app/images/**/*']
};

Now let’s create our first task in Gulp.

The gulpfile.js is composed by one or many tasks, basically you need to create a task for anything you need to perform, like compiling a coffescript into javascript. One task can call one or more tasks.

Let’s name our first task scripts. This task will compile our coffeescript files into javascript, minify and uglify it. After that all files will be concatenated into all.min.js and then it will be placed into dist/script folder, ready to be included in your HTML file.

gulp.task('scripts', function() {  
  // Compile Coffescript, minify and uglify JS
  return gulp.src(paths.scripts)
    .pipe(coffee())
    .pipe(uglify())
    .pipe(concat('all.min.js'))
    .pipe(gulp.dest('dist/scripts'));
});

The second task will be called images. And it will optimise the images and place them into dist/images folder.

gulp.task('images', function() {  
 return gulp.src(paths.images)
    .pipe(imagemin({optimizationLevel: 5}))
    .pipe(gulp.dest('dist/images'));
});

And the third task will be called styles which will grab all the stylesheets, compile the SASS files we may have, concatenate them into main.css and then place it into dist/styles folder.

gulp.task('styles', function () {  
  return gulp.src(paths.styles)
    .pipe(sass())
    .pipe(concat('main.css'))
    .pipe(gulp.dest('dist/styles'));
});

Those are the three main tasks we need in order to have an asset pipeline. And after defining the tasks, how do we run them?

To run any task we we go to the terminal and type gulp <task_name>.

$ gulp scripts
$ gulp styles
$ gulp images

Is there a way to run them all at once?

Yes, we can do that by creating a default task:

gulp.task('default', ['scripts', 'styles', 'images']);  

Now you can run it with the following command line. When it’s finished, take a look at the processed files generated in dist folder:

$ gulp

Lastly, if you want to run all of these tasks for whenever you change any Javascript, SASS or image, you can define a gulp.watch. The code below will fire the proper task in case you change any file. This is particularly good for development environment.

gulp.task('watch', function() {  
  gulp.watch(paths.scripts, ['scripts']);
  gulp.watch(paths.styles, ['styles']);
  gulp.watch(paths.images, ['images']);
});

To run the task above:

$ gulp watch

Why you should consider using an Asset Pipeline in your project?

To me one of the best aspects of the asset pipeline is that I can write my JS files in pure javascript, coffescript or both and I don’t need to worry about compiling coffescript into javascript, compress it or minify it. The same applies to CSS, because I can use SASS to write my stylesheets and get it processed into CSS automatically. That’s really great and doesn’t slow down the development time.