Glad to have your once again. After I've paused this tutorial for some time, I am now back to give you another taste of gulp.
Before we dive into it, I would like to provide you my result of the last home work. Here is the folder structure I got:
- myProject
- app/
- css/
- js/
- sass/
- index.php
- node_modules/
- gulpfile.js
- package.jason
- app/
This folder structure will the basement for our today's tutorial.
So, In this last part of the tutorial I will focus mainly on some plugins and tools that could be very important and very useful for any developer, and how we can organize a gulpfile.js
file.
This tutorial assumes that you have been through the first, second, and third part of these series and you are used to this build tool.
List of some useful plugins
- Gulp-BrowserSync
In previous part we saw how we could use browserSync
to reload our application automatically. But like the name suggests it, browserSync is more about syncing your application.
When you run your application with gulp, in your Terminal
you should see this feed back or something similar from browserSync:
Local: http://localhost:9091
External: http://172.28.64.208:9091
You preview your application on your machine with the local
URL while you can use the External
URL on any other device connected to the same network like you to see the same application. What it means is that your project is accessible/view-able on any device that is connected to the same network with you. Good for testing. Imagine you are testing the responsiveness of your application, you can easily it from any device and have it rendered accordingly without you having to install it there or deploying it. Above all when you scroll your page on one device, it also scrolls it others.
- Auto-loading with gulp-load-plugins
Let's start from this one. Requiring plugins while writing automate tasks can become very heavy in terms of the number of require you have to write. With this plugin you can just ask gulp to require all your tasks automatically. And you may ask me how to access your plugins names because after all you need those names in your pipes. Yes, you are right, gulp-load-plugins
takes a good care of creating those names automatically based on their package's name in camelCase
format, and saves it in an object
that you can easily access. Let's use the gulp-minify-css
case for an example:
var gulp = require('gulp');
var gulpLoadPlugins = require('gulp-load-plugins');
// The object containing plugins name
var plugins = gulpLoadPlugins();
gulp.task('css', function(){
return gulp.src('path/to/source')
.pipe(plugins.gulpMinifyCss('main.js'))
});
You have the possibility to configure it.
- Gulp-rename
This plugin is really great in renaming your files. For example in development you have your css
and js
files named styles.css
and main.js
. After compiling them you could use gulp-rename
to rename them into styles.min.css
and main.min.js
gulp.src(paths.sass)
.pipe(sass())
.pipe(autoprefixer())
.pipe(minifycss())
.pipe(rename({suffix: '.min'}));
- Concatenation with gulp-concat
Likewise the gulp-rename plugin, gulp-concat
is another prestigious plugin that will be in charge of unifying, merging or simply concatenating your javascript files.
return gulp.src(['path/to/file1.js', 'path/to/file2.js'])
.pipe(concat('temp.js'))
.pipe(uglify())
.pipe(rename('final.min.js'))
.pipe(gulp.dest('./app/js/'))
- Gulp-plomber
Plumber is a great plugin which prevents your tasks from stopping when an error occurs while running them. To use you just have to pipe each task through like following:
gulp.src(path.files)
.pipe(pumber()),
.pipe(gulp.dest(path.dest));
- Gulp unCSS
My favorite. It's really a blessing to have this plugin. It takes care of your unused css, which can drastically reduce the weight of your css stylesheets, especially if you are working with framework like Twitter Bootstrap. Check out how you can use it:
return gulp.src('path/to/css/sources')
.pipe(sass())
.pipe(autoprefixer())
.pipe(uncss({
html: ['index.html', 'posts/**/*.html', 'http://example.com']
}))
.pipe(rename({
suffix: '.min'
}))
- gulp-imagemin
This plugin is going to save your day by optimizing your images. It very simple to use.
An example to optimize .png, .jpg, . jpeg, .gif, .svg
return gulp.src('path/to/images'/*.{png,jpg,jpeg,gif,svg}')
.pipe(imagemin());
- gulp-rev
A great plugin to help revise your code before production.
gulp.task('rev', ['less', 'scripts'], function() {
return gulp.src(['dist/**/*.css', 'dist/**/*.js'])
.pipe(rev())
.pipe(gulp.dest('dist'));
});
- Critical CSS
Critical CSS is also another great plugin. It role is inject any required css and javascript to help load your content before the fold
without blocking. This may sound weird, but this is the problem. You may know Google PageSpeed Insights which help determine the speed of web pages on desktop and on mobile devices.
Javascript and css slow the loading of pages, and google assumes that anything before the fold
should load instantly. That's where Critical css comes in. It will inject all the required Css in your HTML tags, which gives you some inline CSS. And this has some advantages such as speeding up the loading time.
I am not really convainced to use it yet, I still think I can get other alternatives to solve the problem. So I will not really be covering it, you can still go to its page, and I really encourage you to check out this video of Patrick Hamann (The Guardian) if you really want to see how people enjoyed such practices.
- Other plugins
There are some other plugins you may also like to look at such as gulp-html-extend, autoprefixer, gulp-iconfont, gulp-sourcemaps, gulp-util.
We've covered some of them in this series. So there many other plugins out there that may feat some of your projects.
Project set up
We have gone though many plugins, and we are all excited about it. Oh thank God!
The other thing you must also consider when working with gulp is the organization of your tasks within your gulpfile.js
file, which implises how to name your tasks, which task to watch or not, which task to run in production or which ones to run before production, etc.
So let's look at that quickly explained as step bellow.
Note that these steps are not a standard that you must follow, it's just something I do and see some other developers do too.
- First, start from requiring all needed plugins; use one
require()
function and comma separation or usegulp-load-plugins
- Defines variables to store paths of your files location
- Defines your CSS task
- Defines your Script task
- Define your HTML task
- Define you image task
- Define any syncing task, like browserSync
- Define a needed cleaning task
- Define build tasks
- Define watch tasks
- Define a gulp
default
task
Always try to add a comment block before each step to explain what it does.
Let's create a sample gulpfile.js
file based on these guide lines:
// ////////////////////////////////////////////////
//
// SAMPLE GULPFILE.JS
// More comment ...
// // /////////////////////////////////////////////
// ////////////////////////////////////////////////
//
// Required plugins
//
// // /////////////////////////////////////////////
var gulp = require('gulp'),
plugin1 = require('gulp-plugin1'),
plugin2 = require('gulp-plugin2'),
plugin3 = require('gulp-plugin3');
// ////////////////////////////////////////////////
//
// Create configuration variable
//
// ////////////////////////////////////////////////
var config = {
html: [
'path/to/html/files'
],
scss:[
'path/to/scss/files'
],
scripts:[
'path/to/script/files'
]
};
// ////////////////////////////////////////////////
//
// Styles Tasks
//
// ///////////////////////////////////////////////
gulp.task('styles', function() {
gulp.src(config.scss)
.pipe( ... )
. ...
;
});
// ////////////////////////////////////////////////
//
// Scripts Tasks
//
// ///////////////////////////////////////////////
gulp.task('scripts', function() {
return gulp.src(config.scripts)
.pipe( ... )
. ...
;
});
// ////////////////////////////////////////////////
//
// HTML Tasks
//
// // /////////////////////////////////////////////
gulp.task('html', function(){
gulp.src(config.html)
.pipe( ... )
. ...
;
});
// ////////////////////////////////////////////////
//
// Images Tasks
//
// // /////////////////////////////////////////////
gulp.task('images', function() {
return gulp.src(config.images)
.pipe(cache(imagemin()))
. ...
;
});
// ////////////////////////////////////////////////
//
// Browser-Sync Tasks
//
// // /////////////////////////////////////////////
gulp.task('browser-sync', function() {
browserSync({
server: {
baseDir: "./app/"
}
});
});
// ////////////////////////////////////////////////
//
// Cleaning Tasks
//
// // /////////////////////////////////////////////
gulp.task('clean', function() {
return gulp.src(['dist/styles', 'dist/scripts', 'dist/images'], {read: false})
.pipe(clean());
});
// ////////////////////////////////////////////////
//
// Build Tasks
//
// // /////////////////////////////////////////////
// task to run build server to test the final app
gulp.task('build:serve', function() {
browserSync({
server: {
baseDir: "./build/"
}
});
});
// task to create build directory of all files
gulp.task('build:create', function(){
//...
});
// task to removed unwanted files from build folder
gulp.task('build:remove', function () {
// ...
});
// Task to start building
gulp.task('build', ['build:create', 'build:remove']);
// ////////////////////////////////////////////////
//
// Watch Tasks
//
// // /////////////////////////////////////////////
gulp.task ('watch', function(){
gulp.watch(config.scss, ['styles']);
gulp.watch(config.scripts, ['scripts']);
gulp.watch(config.html, ['html']);
});
// ////////////////////////////////////////////////
//
// Gulp Default Task
//
// // /////////////////////////////////////////////
gulp.task('default', ['scripts', 'styles', 'html', 'browser-sync', 'watch']);
.gitignore file
I wanted to make mention of that because when you look inside your node_modules
folder, you can see that it contains tones of files and folder that are heavy, I mean really heavy and you don't want to waste your entire day trying to copy them while deploying or while giving the project to someone else. You don't also want to track it with git, since you already have your package.json
file, you can always have them back.
So, to prevent it, use a .gitignore
file is which you can disallow the tracking of such folders and files. The file could have something like:
## Build Systems
node_modules/
bower_components/
.sass-cache
*.css.map
build/
dist/
Bottom line
As I said, the Gulp world is complex and multiform. What I said can be said by another person in different manner and it will still work. One thing you should always consider is your context and your project requirements. You can see a huge project with a very little gulpfile or the opposite. I think the perfect technic is the one that works for you and satisfies your requirements.
If you like this tutorial, please do not hesitate to share it with friends, I will really appreciate the support.
Last updated 2024-01-11 UTC