It seems like you are using an ad blocker. To enhance your experience and support our website, please consider:

  1. Signing in to disable ads on our site.
  2. Sign up if you don't have an account yet.
  3. Or, disable your ad blocker by doing this:
    • Click on the ad blocker icon in your browser's toolbar.
    • Select "Pause on this site" or a similar option for lancecourse.com.

Automate your workflow with Gulp - part 2

By zooboole

Welcome to the second part of our tutorial on Gulp build system. In the previous part we saw how we can set up a simple build system based on Gulp.

We were able to install node, npm, and gulp. Then we created a simple gulpfile.js in which we defined a simple task that could minify our css.

Based on that little exercise we had noticed that every time we make any changes, we have to go back to our command line and run gulp mincss which is our task name. Until then, our system was not automatic. We wish it could do that job every time we use ctrl+s. Beside, we want it to refresh our browser for us and prompt a notification to tell us if the tasks were executed successfully.

Once again welcome to this part. I am zooboole your tutor all along this tutorial.

In this part I will take you to the discovery of our third section of the gulpfile.js which will allow us to watch our files and run our tasks runners whenever we save. also, aside our minified css task, we are going to add the possibility of compiling a sass file instead of using raw css, then display a notification when everything is done successfully.

From here you should know that all this jobs or tasks correspond to gulp packages that we need to download in our project.

To start, here is my current folder structure:

  • Build/
    • index.html
    • package.json
    • gulpfile.js
    • node_modules/
      • gulp/
      • gulp-minify-css/
    • main.css

Install required packages

cd to your project folder and run the following commands one by one to install the required packages:

npm install --save-dev gulp-notify

npm install --save-dev gulp-sass

Add a watch task and automate the system

Gulp provides an object called watch which is just like the src and the dest objects. We can use the watch object to ask gulp to watch over a given task. That means that Gulp will surveil the file in case it\'s modified.

Add the following code to your gulpfile.js to start watching your main.css file:

gulp.watch(\'main.css\', function(){
    console.log(\'seen\');
});

Your final gulpfile.js should look like this:

var gulp = require(\'gulp\');

var minifyCss = require(\'gulp-minify-css\');

gulp.task(\'mincss\', function(){

    return gulp.src(\'main.css\')

        .pipe(minifyCss())

        .pipe(gulp.dest(\'main\'));

});

gulp.watch(\'main.css\', function(){
    console.log(\'seen\');
});

Now go to your command line and run gulp mincss again. If everything happened as expected you should see a message: seen like in the image below:

Gulp watch

The watch object will still be listening to any changes made in the main.css file, and display seen everytime until you press ctrl+c to stop it. Cool!

The watch function takes two arguments: the file(s) to watch and a call to action. The second argument can be a closure (anonymous function) or a javascript object.

Notice that in time we may be adding more tasks to our gulpfile.js file. We could have a task script to manage our javascript files, a task connectPHP to run a php server, etc. It could become hard to manage it with this way of watching. Let assume we have three files to watch, we will have to write:

gulp.watch([\'file1.css\', \'file2.txt\', \'file3.js\'], function(){

    console.log(\'seen\');

});

It will work fine, but I personaly have two main problems with this practice: One, it looks dirty. I have to write the whole file name. Two, it\'s going to display the same massage (\'seen\') everytime any of the files is changed, while I wish I could know when a particular file is changed.

The best way to handle the dirty part is to create an object of paths like following:

var paths = {

    css:[\'path/to/style1.css\', \'path/to/style2.css\'],
    script:[\'path/to/script1.js\', \'path/to/script2.js\']

};

gulp.watch(paths.css, function(){

    console.log(\'seen css changes\');

});

gulp.watch(paths.script, function(){

    console.log(\'seen javascript changes\');

});

That looks good, and gives us the chance to know when our css is changed or when is our javascript is changed.

Another powerful thing to notice is the second argument. Since we can use a closure as argument, imagine we pass in there a whole task? so that we have something like this:

gulp.watch(paths.css, [\'mincss\']);

You agree with me that, this looks so clean. Now, with all these little changes, let\'s apply it to our gulp file and see how it looks in overall:

var gulp = require(\'gulp\');

var minifyCss = require(\'gulp-minify-css\');

var paths = {

    css:[\'main.css\'],
    text:[\'test.txt\']

};

gulp.task(\'mincss\', function(){

    return gulp.src(\'main.css\')

        .pipe(minifyCss())

        .pipe(gulp.dest(\'main\'));

});

gulp.watch(paths.css, [\'mincss\']);

While all this is fine, imagine we have more tasks to watch. How do we run it from our command line? Let assume the following case:

var gulp = require(\'gulp\');

var minifyCss = require(\'gulp-minify-css\');

var coffee = require(\'gulp-coffee\');

var paths = {

    css:[\'main.css\'],
    script:[\'script.coffee\']

};

gulp.task(\'mincss\', function(){

    return gulp.src(\'main.css\')

        .pipe(minifyCss())

        .pipe(gulp.dest(\'main\'));

});

gulp.task(\'scripts\', function(){

    return gulp.src(paths.script)

        .pipe(coffee())

        .pipe(gulp.dest(\'js\'));

});

gulp.watch(paths.css, [\'mincss\']);

gulp.watch(paths.script, [\'scripts\']);

When you run gulp mincss it will be watching the css file and our coffee script file. But when you change the coffee script file, it will no be watched, the css file will not be watched either. Meaning, the watching happen only when you change your css file. Same thing happens when you decide to watch the script task. Though this could be usefull sometimes in terms of savings of resources.

To palliate to the problem we need to gather all tasks watched into a single watching task that can be called once and it could watch all our tasks at once:

var gulp = require(\'gulp\');

var minifyCss = require(\'gulp-minify-css\');

var coffee = require(\'gulp-coffee\');

var paths = {

    css:[\'main.css\'],
    script:[\'script.coffee\']

};

gulp.task(\'mincss\', function(){

    return gulp.src(\'main.css\')

        .pipe(minifyCss())

        .pipe(gulp.dest(\'main\'));

});

gulp.task(\'scripts\', function(){

    return gulp.src(paths.script)

        .pipe(coffee())

        .pipe(gulp.dest(\'js\'));

});

gulp.task(\'watcher\',function(){

    gulp.watch(paths.css, [\'mincss\']);

    gulp.watch(paths.script, [\'scripts\']);

});

Then all you have to do is to run gulp watcher and all your files will be watched at the same time. Any file you change will be compiled.

There is another way to make things simpler. Instead of you to run gulp watcher you can just run gulp and it will do the work for you. But, right now in our case if you enter gulp you will receive this error:

[11:08:34] Task \'default\' is not in your gulpfile
[11:08:34] Please check the documentation for proper gulpfile formatting

Gulp is requesting us to create another task that we must be named default which is necessary to its functioning.

So, what\'s the default task about? This task takes all the tasks to run in one single object including our watcher task. Now we can change our gulpfile.js into this:

var gulp = require(\'gulp\');

var minifyCss = require(\'gulp-minify-css\');

var coffee = require(\'gulp-coffee\');

var paths = {

    css:[\'main.css\'],
    script:[\'script.coffee\']

};

gulp.task(\'mincss\', function(){

    return gulp.src(\'main.css\')

        .pipe(minifyCss())

        .pipe(gulp.dest(\'main\'));

});

gulp.task(\'scripts\', function(){

    return gulp.src(paths.script)

        .pipe(coffee())

        .pipe(gulp.dest(\'js\'));

});

gulp.task(\'watcher\',function(){

    gulp.watch(paths.css, [\'mincss\']);

    gulp.watch(paths.script, [\'scripts\']);

});

gulp.task(\'default\', [\'watcher\', \'mincss\',\'scripts\']);

I love this one <3.

Compile sass file

To compile a sass file, require our gulp-sass package.

var sass = require(\'gulp-sass\');

Remain your main.css file into main.scss

Pipe it in your css task (even though you can still create a different task for it.)

gulp.task(\'mincss\', function(){

    return gulp.src(\'main.scss\')

        .pipe(sass().on(\'error\', sass.logError))

        .pipe(minifyCss())

        .pipe(gulp.dest(\'main\'));

});

Now delete every thing you have in main.scss and add following code:

$color-title: #333;

h1{
    color:$color-title;
}

Run you gulp command. Now if you check main/main.css you should see:

h1{color:#333}

Happy Sassing!

Display a notification

Adding a notification is one of the easiest things to do with gulp. Just require gulp-notify in your gulpfile.js

var notify = require(\'gulp-notify\');

Then pipe your css through it:

gulp.task(\'mincss\', function(){

    return gulp.src(\'main.scss\')

        .pipe(sass().on(\'error\', sass.logError))

        .pipe(minifyCss())

        .pipe(gulp.dest(\'main\'))

        .pipe(notify(\'Done! master zooboole.\'));

});

All you have to do is just to pass a message to display to notify()

Then run gulp. If every is well, you should see something like this:

enter image description here

Conclusion

Though I planned to introduce live reloading in this part I couldn\'t because it was getting too long. So I have decided to write a third part in this topic. The next part will be exclusively about live reloading.

Thanks for following and as usual, if you like share with others, or you can leave a comment.

Last updated 2024-01-11 UTC