Setting up a workflow with Gulp for fontend development

Published Sep 27, 2017
Setting up a workflow with Gulp for fontend development

The Challenge

When you get the green light to a new web application project, how would you set up a workflow for your frontend development? Let's say LESS and ES6 are the essential technologies that you want to adopt, but writing ES6 for browsers is impossible unless you use Babel or something equivalent to translate ES6 to ES5 which they currently understand, too, writing pre-process CSS is tedious because it needs to be translated to 'actual' CSS before we can use it on our browsers. You need a quick and smooth development workflow like we used to do before these new technologies, without being interrupted by the translation and conversion process.

After many projects I have worked in the past, I finally narrowed it down to using Gulp, Babel and Browserify to help me for setting up the development workflow that I need.

Getting started

1. Directory structure

This is my basic directory structure:


dist/ is where all translated ES6 and LESS files are kept and it is where you should link them up in the link and script tags:

<link href="dist/bundle.min.css" rel="stylesheet">
<script src="dist/bundle.min.js"></script>

fonts/ is where all custom webfonts that I have generated from IcoMoon and Font Squerrel.

If you want to make your icons, website logos, etc into fonts, IcoMoon is great place to generate them for you.

We are going to use Gulp to help us to copy all fonts in fonts/ to dist/fonts/ for distribution.

So when the frontend is ready, these are the basic files and folders that you need to upload or to distribute:


2. package.json

This is the basic setup and dependencies I have in my package.json:

  "name": "[your-project]",
  "description": "[your-project-description]",
  "author": "[your-name]",
  "license": "ISC",
  "dependencies": {
    "es6-docready": "^1.0.0",
    "foundation-icon-fonts": "^0.1.1",
    "foundation-sites": "^6.4.3",
    "jquery": "^3.2.1",
    "jquery-migrate": "^3.0.0",
    "jquery-mobile": "^1.4.1",
    "jquery-ui": "^1.12.1",
    "jquery-ui-bundle": "^1.12.1",
    "material-design-icons": "^3.0.1"
  "repository": {
    "type": "git",
    "url": "[git-url-of-your-project]"
  "devDependencies": {
    "babel-preset-es2015": "^6.16.0",
    "babel-preset-react": "^6.16.0",
    "babelify": "^7.3.0",
    "browserify": "^14.3.0",
    "browserify-shim": "^3.8.12",
    "gulp": "^3.9.1",
    "gulp-clean-css": "^3.0.4",
    "gulp-clone": "^1.0.0",
    "gulp-concat": "^2.6.0",
    "gulp-concat-css": "^2.3.0",
    "gulp-cssimport": "^5.0.0",
    "gulp-htmlmin": "^3.0.0",
    "gulp-less": "^3.3.2",
    "gulp-livereload": "^3.8.1",
    "gulp-sourcemaps": "^1.6.0",
    "gulp-uglify": "^2.1.2",
    "streamqueue": "^1.1.1",
    "vinyl-buffer": "^1.0.0",
    "vinyl-source-stream": "^1.1.0"
  "browser": {
    "jquery": "./node_modules/jquery/dist/jquery.js"
  "browserify-shim": {
    "jquery": "$"
  "browserify": {
    "transform": [

I have recently migrated from Bootsrap to Zurb Foundation because I find the latter has a better grid system.

3. gulpfile.js

And finally this is what I have in my gulpfile.js:

var gulp = require('gulp')
var sourcemaps = require('gulp-sourcemaps')
var livereload = require('gulp-livereload')

// JavaScript development.
var browserify = require('browserify')
var babelify = require('babelify')
var source = require('vinyl-source-stream')
var buffer = require('vinyl-buffer')
var uglify = require('gulp-uglify')

// Less compilation.
var less = require('gulp-less')

// CSS compilation.
var concat = require('gulp-concat')
var cleanCSS = require('gulp-clean-css')
var concatCss = require('gulp-concat-css') // optional

// HTML compilation.
var htmlmin = require('gulp-htmlmin');

// Task to compile js.
gulp.task('compile-js', function () {
    // app.js is your main JS file with all your module inclusions
  return browserify({
    extensions: ['.js', '.jsx'],
    entries: 'javascripts/app.js',
    debug: true
  .transform('babelify', { presets: ['es2015', 'react'] })

// Task to compile less.
gulp.task('compile-less', function () {
  return gulp.src([

// Task to minify css.
gulp.task('minify-css', function () {
  return gulp.src([
  .pipe(cleanCSS({debug: true}))

// Task to minify html.
gulp.task('minify-html', function() {
  return gulp.src('index.html')
    collapseWhitespace: true,
    removeComments: true

// Task to copy fonts to dist.
gulp.task('compile-fonts', function() {
  return gulp.src([

// Task to watch less & css changes.
gulp.task('watch', function () {'javascripts/*.js', ['compile-js'])  // Watch all the .js files, then run the js task'stylesheets/*.less', ['compile-less'])  // Watch all the .less files, then run the less task'stylesheets/*.css', ['minify-css'])  // Watch all the .css files, then run the css task'stylesheets/*.css', ['compile-fonts'])  // Watch all the .css files, then run the font task

// Development:
// Task when running `gulp` from terminal.
gulp.task('default', ['watch'])

// Production:
// Task when running `gulp build` from terminal.
gulp.task('build', ['minify-css', 'compile-fonts', 'compile-js', 'minify-html'])

Gulp will watch any change in the LESS and ES6 code and translate them automatically for you. So you just need to refresh your browser to see the changes.

Using the workflow

To use this workflow, go to your project root directory and run it on your terminal then install the Node packages:

$ npm install

During LESS and ES6 development:

$ gulp watch

When you are ready for distribution:

$ gulp build

You can use the minified HTML index.min.html instead of index.html after the build.


As you can see it is quite a breeze to develop the frontend with Gulp when it is set up and you can work smoothly without worrying about the translation. You can download this sample project using this workflow in GitHub repository. Let me know what you think and what workflow you use for your projects. Any suggestions and errors, or any improvements to add to this workflow, please leave a comment below. Hope this workflow is helpful if you are struggling with the same problem I had.

Discover and read more posts from LAU TIAM KOK
get started