It's Easy to Use: Gulp
We'll learn by doing how to automate processing our website files using gulp, a task runner, thus saving time and improving our productivity.
Hey there, This is my first post on my blog, so I'm excited about it. 😇 Also, It took me the right amount of time to self-host this blog using Ghost. But overall, I'm happy with how I set it up, and it is speedy and smooth.
Recently, I came across Gulp, and I was amazed by its features. I came to know how useful a task runner can be for web developers. So, I just wanted to write about it. So without further adieu, let's get started.
Introduction
What is gulp BTW? Gulp is a task runner or builds runner. We provide some instructions in a file called gulpfile.js
, and it will execute those instructions to get our work done.
We as developers waste too much of our time doing repetitive tasks, so Gulp is a great simple way to automate our repetitive tasks, thus, making us more productive.
Let's say we built a simple static website, and now it's ready to be deployed to production for the world to see. But before that, we'll need to make some optimization(s) like compressing CSS and JS files, so end users don't have to download huge files and thus leading to bad UX.
So now, you compress your HTML, CSS, JS, and Image files from websites like https://minify-html.com/, https://cssminifier.com/, https://jscompress.com/, and https://tinypng.com respectively. You then deploy your code to production. It works, Yay. But wait, you've made a simple spelling mistake. Now, you go back to your editor. Then you'll have to beautify(or prettify) your whole codebase using websites like https://codebeautify.org. You'll then correct your spelling mistake. Again you'll need to compress your files. Now, you push to production. It works, Yay. But wait Still, there's some other spelling mistake...
But isn't there a better way to automate this stuff? The good news is, there is. And that's what we're going to learn today, and it's effortless to use. We'll write all of our code in src/
folder, write a gulp script gulpfile.js
that will compress all of our files, and put it in dist/
folder. You always work with src/
folder and always deploy dist/
folder only(If you deploy src/
folder, then my whole time writing this article will be a waste). With this approach, you don't always have manually to minify(or compress) files or beautify them, you can do it with just one command.
Getting Started
Prerequisites: NodeJS, Yarn(or NPM), and obviously, your codebase of the static website.
-
From the root of your project, run:
$ npm init -y
- This will create a
package.json
file with defaults.
- This will create a
-
Our initial folder structure must be something like this:
. ├── dist ├── package.json └── src ├── assets │ ├── img1.jpg │ └── img2.jpg ├── css │ ├── 01-style1.css │ ├── 02-style2.css │ └── 03-style3.css ├── fonts │ ├── font1.woff │ └── font2.woff ├── index.html └── js ├── 01-app1.js ├── 02-app2.js └── 03-app3.js
- You can see that our CSS/JS files have a numeric prefix. We do this because gulp processes file alphabetically.
- So, for example, If you have 2 CSS files named
custom.css
andlibrary.css,
then gulp will processcustom.css
and thenlibrary.css,
thus all the custom code that you write incustom.css
will be overridden bylibrary.css.
- But we don't want this. So we change their names to
01-library.css
and02-custom.css
. Sweet and simple.
-
Let's add some dependencies, run:
yarn add gulp gulp-autoprefixer gulp-clean gulp-clean-css gulp-concat gulp-htmlmin gulp-imagemin gulp-replace gulp-uglify-es merge-stream # or # npm i --save gulp gulp-autoprefixer gulp-clean gulp-clean-css gulp-concat gulp-htmlmin gulp-imagemin gulp-replace gulp-uglify-es merge-stream
-
Let's understand what each of these packages does:
gulp
: The main toolbox.gulp-autoprefixer
: It will prefix the CSS with Autoprefixer.gulp-clean
: It helps to remove files and folders.gulp-clean-css
: Minify the CSS withcleancss
gulp-concat
: Concatenate files, so all of our CSS/JS files will be produced in just one CSS/JS file. Thus, it helps in reducing the requests count.gulp-htmlmin
: Minify HTMLgulp-imagemin
: Compress imagesgulp-replace
: Replace some text in the files with custom texts.gulp-uglify-es
: Minify JSmerge-stream
: We'll use this to copy other static parts.
-
Finally, create
gulpfile.js
file in the root of your project, run:$ touch gulpfile.js
Enough of the theory, let's dive into code.
Codebase:
Let's start writing our automation script:
-
Let's include all of our packages in
gulpfile.js
:// gulpfile/js let gulp = require('gulp'); let clean = require('gulp-clean'); let concat = require('gulp-concat'); let replace = require('gulp-replace'); let minifyCSS = require('gulp-clean-css'); let uglify = require('gulp-uglify-es').default; let htmlmin = require('gulp-htmlmin'); let autoprefixer = require('gulp-autoprefixer'); let merge = require('merge-stream');
-
Next, let's defile the location of our files in the codebase in
globs
variable:// Location to our files let globs = { dist: './dist', css: './src/css/*.css', js: './src/js/*.js', html: './src/*.html', images: './src/assets/**', fonts: './src/fonts/**' };
-
Now, the first step is to clean the
dist/
folder for any old files, and we'll do that by:// Step: 1 - This will delete the folder and re-create it gulp.task('clean', gulp.series(function() { return gulp.src(globs.dist, {read: false}) .pipe(clean()); }));
-
The second step is to place our
fonts/
directory to thedist/
folder, and we'll not do any compression or optimization to it. Just copy it to thedist/
folder:// Step: 2 - Just copy fonts/ folder gulp.task('fonts', gulp.series('clean', function() { return gulp.src(globs.fonts) .pipe(gulp.dest(globs.dist + '/fonts')); }));
-
Now let's work on our CSS files. We'll take all of our CSS files, concatenate them into one CSS file called
main.min.css
, Apply autoprefixer to it, then minify it and then finally place this CSS file todist/css
folder:// Step: 3 - CSS processing gulp.task('styles', gulp.series('clean', function() { return gulp.src(globs.css) .pipe(concat('main.min.css')) .pipe(autoprefixer()) .pipe(minifyCSS()) .pipe(gulp.dest(globs.dist + '/css')); }));
-
Now let's work on our JS files. We'll take all of our JS files, concatenate them into one JS file called
app.min.js
, minify them, then export them todist/js
folder:// Step: 4 - JS processing gulp.task('js', gulp.series('clean', function() { return gulp.src(globs.js) .pipe(concat('app.min.js')) .pipe(uglify()) .pipe(gulp.dest(globs.dist + '/js')); }));
-
Now let's work on our image files. We'll take all of our Images, compress them, then export them to
dist/assets/
folder:// Step: 5 - Image processing gulp.task('assets', gulp.series('clean', function() { return gulp.src(globs.js) .pipe(imagemin()) .pipe(gulp.dest(globs.dist + '/assets')); }));
-
Finally, let's work on our HTML file:
- In our HTML file, we'll have our
<link>
tags something like this:<link rel="stylesheet" href="css/01-style1.css"> <link rel="stylesheet" href="css/02-style2.css"> <link rel="stylesheet" href="css/03-style3.css">
- So, we'll need to replace these lines with our one CSS file
main.min.css
. - Also, we need to do the same for our JS files to one JS file
app.min.js
. - We'll now minify our HTML file and remove comments also.
- We can do this by these lines:
// Step: 6 - HTML processing gulp.task('html', gulp.series('clean', function() { return gulp.src(globs.html) .pipe(replace(`<link rel="stylesheet" href="css/01-style1.css">`, '')) .pipe(replace(`<link rel="stylesheet" href="css/02-style2.css">`, '')) // Replace this with our one `main.min.css` file .pipe(replace(`<link rel="stylesheet" href="css/03-style3.css">`, '<link rel="stylesheet" href="css/main.min.css">')) .pipe(replace(`<script src="js/01-app1.js"></script>`, '')) .pipe(replace(`<script src="js/02-app2.js"></script>`, '')) .pipe(replace(`<script src="js/03-app3.js"></script>`, '<script src="js/app.min.js"></script>')) .pipe(htmlmin({ collapseWhitespace: true, removeComments: true })) .pipe(gulp.dest('./dist')); }));
- In our HTML file, we'll have our
-
The final step is to build the task, and we can tell gulp with this:
// Step: 7 - Build the task gulp.task('build', gulp.parallel('fonts', 'styles', 'js', 'assets', 'html')); gulp.task('default', gulp.series('build'));
-
That's it; your complete gulp file must look like this: https://gist.github.com/cdadityang/18cd022ab9a8268032f5b5b44641603f
Testing it
We're done with the coding part, let's test it out:
-
We need to add
gulp
to our scripts in ourpackage.json
file. So inpackage.json
file, add:"scripts": { "build": "gulp" }
-
Now from the root directory of your project, run this command:
$ yarn build # or # npm run build
-
Now, go to the
dist/
folder and run your server:$ cd dist/ $ python -m SimpleHTTPServer 3000 # Or any other web server
Summary and conclusion
Let's take a quick look at what we learned today:
- First of all, I introduced myself, so don't forget to connect with me at Twitter or elsewhere.
- We saw a quick introduction to gulp, and we discussed a scenario of how we'll use gulp to solve our problem
- Then we saw what the prerequisites are and we also set up our environment
- Then we wrote our automation script in
gulpfile.js
. - Then we tested our script by adding gulp command to
package.json
file and runningyarn build
, which will export our app todist/
folder. - Finally, we took a quick look at this very summary...
That's it and Let there be the end. 🙏