Building an awesome Front End Workflow with Gulp.js

I’m now around for a while as Front End Developer/Designer and coding for the Web is my passion. I write plain HTML and don’t use Slim or Jade I’m into Emmet and it is awesome. I write SASS with SCSS syntax and mostly plain JS. To deploy these things I use a small Gulp file:

var gulp = require(‘gulp’);
var sass = require(‘gulp-sass’);
var autoprefixer = require(‘gulp-autoprefixer’);
var uglify = require('gulp-uglify');
gulp.task(‘styles’, function() {
gulp.src(‘src/scss/*.scss’)
.pipe(sass({outputStyle: ‘compressed’}))
.pipe(autoprefixer({
browsers: [‘last 2 versions’],
cascade: false
}))
.pipe(gulp.dest(‘assets/css/’));
});
gulp.task('compress', function() {
return gulp.src('src/js/*.js')
.pipe(uglify())
.pipe(gulp.dest('assets/js/'));
});
//Watch tasks
gulp.task(‘default’,function() {
gulp.watch(‘src/scss/*.scss’,[‘styles’]);
gulp.watch('src/js/*.js',['compress']);
});

In the Gulp file above I have two tasks, I simply generate a compressed CSS file out of my main SCSS file(s) and I generate compressed JS files out of all my JS files. As you see this is not really a good way for a Front End Workflow.


At the beginning of October we started a startup project at our university, uooklet — choose.print.discover (more info) and we had to build, for sure, a Landing page. We decided to design and develop an one pager… well I have already implemented a bunch of one pager’s and my philosophy is:

When I do something for university, I want to learn something!

So it came up to my head that I could develop a new Front End Workflow. I already had this messy ugly Gulp file and I wanted to improve my Gulp.js skills.

What do I wanna do with my new Workflow?

  1. Clean up the build directory (my assets folder).
  2. Compress images and vectors (.png .jpg .gif and .svg).
  3. C0mpress and combine the vendor files.
  4. Compress and combine the JS files.
  5. Compress the HTML file.
  6. Compile, compress and autoprefix the SASS (SCSS) files.
  7. Watching all files for changes and deploy them automatically.

Let’s start with the folder structure

This is my folder structure for the project

folder structure

As you can see the folder “src” is the home for all my source files (JS, HTML, SCSS, vendor JS libraries, images, etc.). Everything I write or use is in this folder.

Discover Gulp Step by Step

Requirements

First of all open the Terminal and we need to install node.js (https://nodejs.org/en/download/). After that we check if the installation was successful and we should get something like this:

$ node -v
v0.12.2
$ npm -v
2.7.6

If node and npm are up and running, we install gulp.

$ npm install gulp -g

Now we check if the installation was successful

$ gulp -v
[23:25:38] CLI version 3.9.0
[23:25:38] Local version 3.9.0

Perfect now we have to change the directory to our project folder and via

$ npm init

we create a package.json file. (What is the `package.json` file? HERE you can find more info.)

With the command

$ npm install gulp --save-dev

we install Gulp locally and there is only one step left, create the control file Gulpfile.js and we are ready to go.

Plugins

Gulp has more than 1900 plugins (http://gulpjs.com/plugins/) and I will show you a couple of them, which we will use to provide our workflow. With the command

$ npm install plugin-name --save-dev

we can install Gulp plugins and write the dependency in the package.json file.

Now we are installing all of the needed plugins.

gulp-clean: A gulp plugin for removing files and folders.

$ npm install gulp-clean --save-dev

gulp-imagemin: Minify PNG, JPEG, GIF and SVG images

$ npm install gulp-imagemin --save-dev

gulp-concat: Concatenates files

$ npm install gulp-concat --save-dev

gulp-uglify: Minify files with UglifyJS

$ npm install gulp-uglify --save-dev

gulp-rename: Rename files

$ npm install gulp-rename --save-dev

gulp-minify-html: Minify html with minimize

$ npm install gulp-minify-html --save-dev

gulp-autoprefixer: Prefix CSS

$ npm install gulp-autoprefixer --save-dev

gulp-sass: Gulp plugin for sass

$ npm install gulp-sass --save-dev

After the installation of all used plugins we are able to start with our Gulp file.

Gulpfile

First we have to initialize Gulp.js and all of our plugins.

var gulp = require(‘gulp’);
var clean = require('gulp-clean'),
imagemin = require ('gulp-imagemin'),
concat = require ('gulp-concat'),
uglify = require ('gulp-uglify'),
rename = require('gulp-rename'),
minifyhtml = require ('gulp-minify-html'),
autoprefixer = require ('gulp-autoprefixer'),
sass = require('gulp-sass');

After that we are able to write our first task and use our first plugin.

We now need to define our first task.

gulp.task(‘nameOfTheTask’, function () {

In the second line we refer to the directory (or the file) we want to work with.

return gulp.src('path/to/file/or/directory’)

And in the third line we use the plugin to take some action.

.pipe(clean())

The whole task looks like this:

//Clean up the build directory
gulp.task(‘clean’, function () {
return gulp.src(‘assets/’, {read: false})
.pipe(clean())
});

When we now go to the Terminal and changing the directory to the project folder we can use this task by typing

$ gulp clean

now the whole build directory is cleaned up.

Next we will build a task to compress our images and icons, which looks like this:

//Compress all images
gulp.task(‘images’, function() {
return gulp.src(‘src/images/**/*’)
.pipe(imagemin())
.pipe(gulp.dest(‘assets/img’))
});
//Compress all icons
gulp.task(‘icons’, function() {
return gulp.src(‘src/icons/**/*’)
.pipe(imagemin())
.pipe(gulp.dest(‘assets/icons’))
});

The first three lines are the same as in the clean task, but the fourth line defines the destination where the compressed images should be stored.

After putting some images and icons in the right folders and running

$ gulp images

and

$ gulp icons

All of our images and icons are compressed without a loss of quality.
Really nice.

To compress and combine our vendor and javascript files, we have to write to more tasks:

//Compress and combine vendors
gulp.task(‘vendor’, function() {
return gulp.src(‘src/vendor/*.js’)
.pipe(concat(‘vendor.js’))
.pipe(uglify())
.pipe(rename(‘vendor.min.js’))
.pipe(gulp.dest(‘assets/js/’))
});
//Compress and combine JS files
gulp.task(‘js’, function() {
return gulp.src(‘src/js/*.js’)
.pipe(concat(‘main.js’))
.pipe(uglify())
.pipe(rename(‘main.min.js’))
.pipe(gulp.dest(‘assets/js/’))
});

There is a little difference between the other tasks. Here we use the plugin gulp-concat to combine all files of a specific directory into one file and we use gulp-rename to rename the file in filename.min.js.

Next we want to minify our HTML:

//Compress the HTML file
gulp.task(‘html’, function () {
return gulp.src(‘src/HTML/*.html’)
.pipe(minifyhtml())
.pipe(gulp.dest(‘./’))
});

After the minification of the HTML file we will compile and compress the SASS files:

//Compress, compile and autoprefix SASS (SCSS) files
gulp.task(‘styles’, function() {
return gulp.src(‘src/scss/*.scss’)
.pipe(sass({outputStyle: ‘compressed’}))
.pipe(autoprefixer({
browsers: [‘> 1%’, ‘last 2 versions’],
}))
.pipe(gulp.dest(‘assets/css/’))
});

With the line

.pipe(sass({outputStyle: ‘compressed’}))

we are able to compile and compress the SASS files at once and with the lines

.pipe(autoprefixer({
browsers: [‘> 1%’, ‘last 2 versions’],
cascade: false
}))

we can set prefixes for Internet Explorer or webkit browsers. The autoprefixer plugin provides some options, f.e. browsers for defining which browser prefixes should be inserted (more info).


The Gulpfile is now ready to rock.

But it is a little bit irritating to run every single task after changing a file.

No worries Gulp is awesome and it provides an awesome feature named watch. We only need to write:

gulp.watch(‘directory/or/file/to/watch/for/changes’, [‘taskToRun’]);

For all our tasks this looks like this:

//watch for changes
gulp.task(‘watch’, function() {
gulp.watch(‘src/scss/*.scss’,[‘styles’]);
gulp.watch(‘src/vendor/*.js’,[‘vendor’]);
gulp.watch(‘src/js/*.js’,[‘js’]);
gulp.watch(‘src/HTML/*.html’,[‘html’]);
gulp.watch(‘src/icons/**/*’,[‘icons’]);
gulp.watch(‘src/images/**/*’,[‘images’]);
});

To run all tasks at the beginning of the gulp process I write two more tasks:

//start the runAll and watch task at the beginning
gulp.task(‘default’, [‘runAll’, ‘watch’]);
//run all tasks
gulp.task(‘runAll’, [‘images’, ‘icons’, ‘vendor’, ‘js’, ‘html’, ‘styles’]);

Now we only need to type

$ gulp

in the Terminal and our Gulp process is up and running.

You can fork or download the whole structure and Gulpfile here.

If you got any questions or issues simply tweet to @mhlick.


Thx for reading have an awesome day and never forget:

Do what you love and love what you do!

All the best

Matthias

P.S. thx to my buddy Mha for proofreading.