Hey there, New member here and this is my first dev post, so I'm really excited about it. 😇
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.
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 HTML -
gulp-imagemin
: Compress images -
gulp-replace
: Replace some text in the files with custom texts. -
gulp-uglify-es
: Minify JS -
merge-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 the dist/
folder, and we'll not do any compression or optimization to it. Just copy it to the dist/
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 to dist/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 to dist/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'));
}));
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:
Testing it
We're done with the coding part, let's test it out:
We need to add gulp
to our scripts in our package.json
file. So in package.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. 🙏
Top comments (2)
I've used Gulp 4 years ago, and it's a pain having to use it now (my tasks are super complex). I would recommend checking first if Webpack offers what you are after, since it's more recent and comes out of the box with the most popular JS frameworks and scaffholders
Hey, Thanks for pointing it out. I'm familiar with Webpack(I use it and customize a bit on my react apps). I found Webpack to be a little sophisticated tool, but that is justified provided it solves more complex problems quickly.
For my first article, I wanted to focus on something simple and be more focused on beginners. I think I'll write sometime about Webpack in this series. Thanks again 😀