Gulp is a task runner or bundler built on Node.js and npm, used for automation of time-consuming and repetitive tasks involved in web development like minification, concatenation, optimization, etc.
Gulp is in many ways similar to Webpack, although Gulp is intended for smaller frontend projects.
Follow the steps below to install and configure your Gulp project.
1. Check node, npm, and npx
You will need node, npm, and npx. Check if they’re installed:
node -v
npm -v
npx -v
If they are not installed, run these commands to install the latest versions globally:
npm install npm@latest -g
npm install node@latest -g
npm install npx@latest -g
2. Create a Project
Your project may contain two folders: the src folder that will contain the original files, and the assets folder that will include the files compiled by Gulp. Put the HTML file in the root of your project.
gulp-project/
└── assets/
└── src/
│ └── css/
│ └── global.scss
│ └── main.scss
│ └── ...
│ └── img/
│ └── js/
│ └── script1.js
│ └── script2.js
│ └── ...
└── index.html
3. Create a JSON File
Open a CDM. Type the path to your project, for example:
cd C:\Users\Shark\Documents\Projects\gulp-project
Next, run the command:
npm init
This will guide you through giving your project a name, version, description, etc. You will see some text, and the CMD will offer you to add some information about your project. Fill out the fields or press Enter to leave them blank. Below is an example of partially filled-out notes:
package name: (gulp-project)
version: (1.0.0)
description: This is a sample project
entry point: (gulpfile.js)
test command:
git repository:
keywords:
author: Shark
license: (ISC)
Press Enter and you will see that the package.json has been created in the root of your project:
gulp-project/
└── assets/
└── src/
│ └── css/
│ └── global.scss
│ └── main.scss
│ └── ...
│ └── img/
│ └── js/
│ └── script1.js
│ └── script2.js
│ └── ...
└── index.html
└── package.json
Here is the content of the package.json file so far:
{
"name": "gulp-project",
"version": "1.0.0",
"description": "",
"main": "gulpfile.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Shark",
"license": "ISC"
}
4. Install Gulp
Use the command below to install Gulp CLI that allows launching tasks — it should be installed globally:
npm i gulp-cli -g
Next, install Gulp package in your project:
cd C:\Users\Shark\Documents\Projects\gulp-project
npm i gulp -D
After that, a folder named node_modules and a file named package-lock.json should appear in the root of your project:
gulp-project/
└── assets/
└── node_modules/
└── src/
│ └── css/
│ └── global.scss
│ └── main.scss
│ └── ...
│ └── img/
│ └── js/
│ └── script1.js
│ └── script2.js
│ └── ...
└── index.html
└── package-lock.json
└── package.json
5. Install Plugins
You need to install a minimum of useful plugins to compile and compress your CSS and JS files, as well as to compress images and do other things.
Run the command below:
npm i -D gulp-sass node sass gulp-autoprefixer gulp-cssnano gulp-concat gulp-uglify gulp-rename gulp-imagemin gulp-changed gulp-clean browser-sync
It will install the following plugins locally in your project:
- gulp-sass and node sass: transform Sass into CSS
- gulp-autoprefixer: adds vendor prefixes to CSS rules
- gulp-cssnano: minifies CSS
- gulp-concat: merges several CSS or several JS files
- gulp-uglify: minifies JS
- gulp-rename: adds .min to the name of a minified file
- gulp-imagemin: minifies images
- gulp-changed: detects whether files were changed and excludes unchanged files: every time you run gulp all your files would not be rewritten regardless of whether the source files were changed
- gulp-clean: clears the build directory and deletes everything in it
- browser-sync: provides you with a simple web server and auto-reloads the page in all browsers on all devices
After installing plugins, your package.json will look like the one below.
{
"name": "gulp-shark",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Shark",
"license": "ISC",
"devDependencies": {
"browser-sync": "^2.26.7",
"gulp": "^4.0.2",
"gulp-autoprefixer": "^6.1.0",
"gulp-changed": "^4.0.0",
"gulp-clean": "^0.4.0",
"gulp-concat": "^2.6.1",
"gulp-cssnano": "^2.1.3",
"gulp-imagemin": "^6.0.0",
"gulp-rename": "^1.4.0",
"gulp-sass": "^4.0.2",
"gulp-uglify": "^3.0.2"
}
}
5. Configuration
Create gulpfile.js in the root of your project. Add the following configuration for installed plugins:
const {
src,
dest,
parallel,
series,
watch
} = require('gulp');
// Load plugins
const uglify = require('gulp-uglify');
const rename = require('gulp-rename');
const sass = require('gulp-sass');
const autoprefixer = require('gulp-autoprefixer');
const cssnano = require('gulp-cssnano');
const concat = require('gulp-concat');
const clean = require('gulp-clean');
const imagemin = require('gulp-imagemin');
const changed = require('gulp-changed');
const browsersync = require('browser-sync').create();
// Clean assets
function clear() {
return src('./assets/*', {
read: false
})
.pipe(clean());
}
// JS function
function js() {
const source = './src/js/*.js';
return src(source)
.pipe(changed(source))
.pipe(concat('bundle.js'))
.pipe(uglify())
.pipe(rename({
extname: '.min.js'
}))
.pipe(dest('./assets/js/'))
.pipe(browsersync.stream());
}
// CSS function
function css() {
const source = './src/scss/main.scss';
return src(source)
.pipe(changed(source))
.pipe(sass())
.pipe(autoprefixer({
overrideBrowserslist: ['last 2 versions'],
cascade: false
}))
.pipe(rename({
extname: '.min.css'
}))
.pipe(cssnano())
.pipe(dest('./assets/css/'))
.pipe(browsersync.stream());
}
// Optimize images
function img() {
return src('./src/img/*')
.pipe(imagemin())
.pipe(dest('./assets/img'));
}
// Watch files
function watchFiles() {
watch('./src/scss/*', css);
watch('./src/js/*', js);
watch('./src/img/*', img);
}
// BrowserSync
function browserSync() {
browsersync.init({
server: {
baseDir: './'
},
port: 3000
});
}
// Tasks to define the execution of the functions simultaneously or in series
exports.watch = parallel(watchFiles, browserSync);
exports.default = series(clear, parallel(js, css, img));
The pipe() method is used to chain multiple tasks. The first task to be executed should be placed first. The second one would be piped to the first, and the third one would be piped to the second task.
Below are the detailed descriptions of each function.
Clean Assets Function
This function enables the gulp-clean plugin that clears the build directory (/assets) and deletes everything in it. As you don’t need Gulp to read the contents of the files, use read: false to speed up builds.
function clear() {
return src('./assets/*', {
read: false
})
.pipe(clean());
}
JS Function
Here’s the code for the JS function:
function js() {
const source = './src/js/*.js';
return src(source)
.pipe(changed(source))
.pipe(concat('bundle.js'))
.pipe(uglify())
.pipe(rename({
extname: '.min.js'
}))
.pipe(dest('./assets/js/'))
.pipe(browsersync.stream());
}
This function called js() is doing several things. Gulp is first running the src() function to load the source directory of the JS files (./src/js/*.js). The asterisk (*) means Gulp will search for all files with the .js extension inside the js folder. It’s using the constant that has been created earlier — const source. After src(), several other tasks are executed:
- changed(): runs the gulp-changed plugin
- concat(): merges all the JS files into one JS file
- uglify(): minifies JS files
- rename(): adds .min to the name of the compiled file
- dest(): tells Gulp to put the final CSS file in the /assets folder
- browsersync.stream(): runs the browser-sync plugin
CSS Function
Here’s the code for the CSS function:
function css() {
const source = './src/scss/main.scss';
return src(source)
.pipe(changed(source))
.pipe(sass())
.pipe(autoprefixer({
overrideBrowserslist: ['last 2 versions'],
cascade: false
}))
.pipe(rename({
extname: '.min.css'
}))
.pipe(cssnano())
.pipe(dest('./assets/css/'))
.pipe(browsersync.stream());
}
This function called css() is doing several things. Gulp is first running the src() function to load the source directory of the SCSS files (./src/scss/main.scss). It’s using the constant that has been created earlier — const source. After src(), several other tasks are executed:
- changed(): runs the gulp-changed plugin
- sass(): compiles the SCSS files to one CSS file
- autoprefixer(): adds vendor prefixes
- rename(): adds .min to the name of the compiled file
- cssnano(): minifies the CSS file
- dest(): tells Gulp to put the final CSS file in the /assets folder
- browsersync.stream(): runs the browser-sync plugin
Images Function
Here’s the code for the images function:
function img() {
return src('./src/img/*')
.pipe(imagemin())
.pipe(dest('./assets/img'));
}
Like JS and CSS functions, this function runs the src() function to load the source directory, then runs imagemin() to minify the images and dest() to put the final files in the /assets folder.
Watch Function
When you run the watch() function, it will watch your files to detect any changes. After that, it will run any number of tasks you tell it to. You don’t have to keep manually running gulp after every code change.
Here’s the code for your Gulp watch task:
function watchFiles() {
watch('./src/scss/*', css);
watch('./src/js/*', js);
watch('./src/img/*', img);
}
Here you list folders in the source directory with files you want to be watched.
BrowserSync Function
This function runs the browser-sync plugin. Here’s the code:
function browserSync() {
browsersync.init({
server: {
baseDir: './'
},
port: 3000
});
}
port: 3000 means your project will be available at http://localhost:3000. And the base directory is the root of your project (./).
6. Commands
The commands you will have to use the most often in the CMD:
- gulp: run this command after you change the gulpfile.js file
- gulp watch: run this command to watch the files for changes every time you launch your project
The final file structure:
gulp-project/
└── assets/
└── node_modules/
└── src/
│ └── css/
│ └── global.scss
│ └── main.scss
│ └── ...
│ └── img/
│ └── js/
│ └── script1.js
│ └── script2.js
│ └── ...
└── gulpfile.js
└── index.html
└── package-lock.json
└── package.json