Automate Your Fancy Build Streams With Gulp JS

Naren Yellavula
Dev bits
Published in
9 min readFeb 7, 2017

--

Note: This is a step by step guide and can consume a good amount of your time. Be prepared!

Gulp is funny to use

Hello, Full stack developers. If you are not using any build system, then you are losing a lot of productivity. In many cases, you will be developing your code with an idea of maintainability and optimization. Our JavaScript and other Markup code should be placed in a proper location while serving from a web server. If you never heard about Gulp or Grunt you are unlucky. But if you have had already, this article strengthens your knowledge. This topic is quite popular in the Front-end development field. But for full stack developers, no. I have seen a lot of them underestimating the power of process streaming tools like Gulp or Grunt or WebPack.

I recently used Gulp effectively in my work to automate a lot of boring stuff. I hope you too can from now.

Why we need a build system?

In the Ice age of front end development, developers used to write code and manually update files wherever it is required. They steadily learned from Google Developer Network other places about how concatenation and minification of HTML, CSS, and JS can improve the page speeds and hence the customer experience. Even though the page speeds and resource(images) loading times may depend on various factors(DB, Latency etc). It is your responsibility as a full stack developer to optimize all the sensitive parts of a complex web application. So here that sensitive part is the browser.

When you serve web resources(HTML, CSS, JS) from a web server(Apache or Nginx), the page speeds mainly bet on bandwidth. If your files are huge (with thousands of lines of code and hundreds of KB), then your website may not fare well. In another scenario, if you are loading too many files, it can also cause a glitch in the User Experience(UX).

What to do to improve the Web experience?

The things we are building here:

  • Minify your files to reduce the size
  • Pack or bundle your files into a single file and serve it

For developers, doing these things manually is a painful task. Luckily we got a great build stream automation tool like Gulp. We can define any tasks and can ask gulp to excute them.

Seeing is Believing

I am going to show now a working application of Gulp. I create a project called workspace with two folders in it.

  • src/: where are all source files reside for the project
  • build/: where all minified and concatenated files appear

Before rushing, we should know what are the perquisites needed for this Gulp to work. You should have a working copy of node and npm in your computer. If you don’t have them follow these guides.

If you are using a Mac OS X machine, you can install node using HomeBrew

Node uses the V6 engine’s C++ library for its executions. If you have a Google Chrome browser installed on your computer, you already have that library. Otherwise, you can easily download all dependencies for the node. After installing node and NPM, you need to install gulp using this command

$ npm install --global gulp-cli

Now my project is the workspace folder.

Here we have a nice folder structure(personal taste). All source files will be in the src/ folder. All the minified files and concatenated files will lie in the build/ folder. index.html can also be minified.

Now in the project folder install gulp

$ npm install --save-dev gulp

Now we have the gulp. Next, we should give few instructions to gulp. We create a gulp file to do that. It is a JavaScript file with tasks defined in it. Gulp understands those tasks and executes them.

node_modules is created by the above command

Starting the optimization

Now let me add HTML bare body to index.html

<html>
<head>
<title> The simplest HTML example
</title>
</head>
<body>
<h1> This is an HTML Page </h1>
</body>
</html>

This file is a very toy thing. But in your project, this file can reach a few thousands of lines of markup code. So keeping it original(with spaces & tabs) is not good.

The first good habit is to keep source in src/ folder instead of sprinkling it here and there. So I copy the index.html to src/

$ cp index.html src/

Now I should assign a task to Gulp for minifying this index.html in src/ to the index.html in the project directory. For that, I should create a gulpfile. For supplying minifying logic of HTML, we should install a plugin called “gulp-minify-html”. Gulp is a task definer and executor but you should help Gulp by telling how to minify HTML. This is such a plugin where that logic is already written. You can write your custom logic too.

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

Now add content to the gulp file.

// gulpfile.jsvar gulp = require("gulp");
var minifyHtml = require("gulp-minify-html");
gulp.task("minify-html", function(){

gulp.src("src/index.html")
.pipe(minifyHtml())
.pipe(gulp.dest('.'));
});

In the above gulp file, these actions are defined:

  • Import gulp to create tasks.
  • Import gulp-minify-html to minify the HTML file
  • Create a task called minify-html

What is happening here?

A gulp task inputs two arguments. task_name and function_handler

The task name is used for gulp to identify the task to execute whereas the function handler is the actual execution command list. If you see, we are piping a set of instructions one after the other. The essence of the Gulp is in that chaining. Let us write those instructions in plain English:

  • Load source file from given path. Here it is from src/index.html
  • Apply minifyHtml function on that loaded content
  • Output the minified file to index.html in the project root

Now save the file and run this command from project root (i.e Workspace).

$ gulp minify-html

It minifies the HTML from src/index.html and puts it in the project root.

Now if we look at the minified index.html File, it looks like

<html><head><title>The simplest HTML example</title></head><body><h1>This is an HTML Page</h1></body></html>

We ordered Gulp to do something and it did exactly. Similarly, we can minify CSS, minify JS, join JS files into a single one, indent files, and much more.

Here I install necessary plugins to the Gulp for performing above tasks.

$ npm install --save-dev gulp-minify-html
$ npm install --save-dev gulp-minify-css
$ npm install --save-dev gulp-uglify
$ npm install --save-dev gulp-concat

All these plugins will be saved in your node_modules directory in the project root.

Before minifying web resources(JS, CSS) I will create a few dummy scripts. First a javascript file

// src/js/script1.jsvar foo = 10;
console.log("foo is", foo)

Now create another JS file in src/js. These files are simple here but in your project, they may span to many thousands of lines of code.

// src/js/script2.jsvar bar = 20;
console.log("bar is", bar);

Create a dummy CSS file in src/css directory

/* src/css/custom.css   */body {
background-color: red;
}
.myDiv {
margin-left: 10%;
margin-top: 15%;
}

The directory structure looks like this.

Now I re-modify my gulpfile to add imports and tasks for minifying, joining of CSS and JS files.

var gulp = require("gulp");
var minifyHtml = require("gulp-minify-html");
var minifyCss = require("gulp-minify-css");
var uglify = require("gulp-uglify");
var concat = require("gulp-concat");
gulp.task("minify-html", function(){

gulp.src("src/*.html")
.pipe(minifyHtml())
.pipe(gulp.dest('.'));
});
gulp.task("merge-minify-js-css", function(){
gulp.src("src/js/*.js")
.pipe(concat("main.min.js"))
.pipe(uglify())
.pipe(gulp.dest("build/js"));
gulp.src("src/css/*.css")
.pipe(concat("custom.min.css"))
.pipe(minifyCss())
.pipe(gulp.dest("build/css"));
});

Above code is clear for you by now. *.js means for all js files in the directory.

Once again in plain English:

  • Import all necessary functions
  • Create task with subtasks in it
  • One subtask is to Concatenate multiple JS files and minify. Then output main.min.js to build/js
  • Another subtask is to concatenate CSS files into a single one and minify. It also produces a custom.min.css to build/css/

Now let us save and run this gulpfile with tasks

Gulp finished both the tasks and now you will be able to see the newly created minified files in the tree.

observe the build/ folder

And minified files looks like

Since minifying is a process of removing white space characters and new lines, it can reduce the file size to a great extent which in turn boost the web page load speeds.

Can’t I execute all tasks in one go?

Yes, you can. For that gulp provides a task called “default”. If you feel like you should execute a list of tasks with a simple command then add these lines to above gulp file.

// append to gulpfile.jsgulp.task("default", ["minify-html", "merge-minify-js-css"]);

Now you can execute all tasks in one single go with just gulp command.

$ gulp

Do I need to run gulp command every time I change my source files?

In order to run the code, you cannot directly edit minified files. Instead, you modify source files then will run gulp command. But is it a simple thing. For every small modification, you need to run gulp. In order to make this process automated, gulp provides you watchers to your source files. Just run a watcher, then modify the source code. Gulp will take care of building files on the fly whenever changes occurred to watching files.

Here we fragmented HTML, CSS and JS tasks. Then started watching those files and attaching a task to particular directory change.

// Rerun the task when a file changesgulp.task('watch', function() {

gulp.watch(paths.scripts, ['merge-minify-js']);
gulp.watch(paths.styles, ['merge-minify-css']);
gulp.watch(paths.html, ['minify-html']);
});// Add watch to the default tasksgulp.task("default", ["watch", "minify-html", "merge-minify-js", "merge-minify-css"]);

Now when you run gulp command, it starts a never ending watcher which sits there and silently looks for changes. When a specific file is changed, it executes the task associated with it.

It means when we modify CSS files, CSS minification task will run automatically. This is really helpful if developers are adding changes continuously and build is automatically generated.

Other taking points

Here we used Gulp for basic UI tasks. Since it runs on the node, you can give operating system commands and custom utility functions for gulp. For housekeeping and periodic tasks, watching tasks you can use Gulp. You can also build work stream for git releases and build files with it.

Anyway, I think now you got a basic idea of what Gulp is and how it boosts your productivity by creating automated build streams from a simple configuration file.

--

--