Drupal + Grunt + Browsersync: Part 2

Posted By Chris Keller on Wednesday, May 4, 2016 - 14:26

This is part 2 of this blog series. Part 1 covers setting up Grunt and Browsersync, this part will focus on expanding what we created in part 1. It will focus on adding image compression to our Grunt setup. The methods used for image compression aren’t super important but setting up a watcher and using the newer Grunt plugin can be useful for many other things.

Compressing images

One of the things I often forget to do or don’t have the time to do manually, is compress images. By adding this to Grunt we don’t have to remember, it will do the work for us.


Let’s add this in:

npm install grunt-contrib-imagemin --save-dev

You can read more about what imagemin does here:


We’ll need to add this to our Gruntfile.js to load the plugin:


Next we’ll add an entry to be able to run the image compression:

  1. imagemin: {
  2.   dist: {
  3.         files: [{
  4.           expand: true,
  5.           cwd: 'images/source/',
  6.           src: ['**/*.{png,jpg,gif,svg}'],
  7.           dest: 'images/optimized/'
  8.        }]
  9.     }
  10.  }

This will find any images found in the images/source directory and output a compressed version to the images/optimized. Make sure these directories are created and have appropriate file permissions so Grunt can read and write to them.

We need to tell Grunt to run our imagemin entry. In the terminal enter:

grunt imagemin

This should do what we wanted and compress all the images in images/source. This is nice, but it isn’t that automatic. It would be great if Grunt could just watch that directory and compress any image we place there without us telling it to.


We’ll add a watcher to do that:

npm install grunt-contrib-watch --save-dev

We can set the watcher to watch anything we want. In this case we’ll have it watch the images/source directory for any new files and run our imagemin entry when it detects a change.

Let’s add our watch entry into our Gruntfile.js:

  1. watch: {
  2.   images: {
  3.     files: ['images/source/*.{png,jpg,gif,svg}'],
  4.     tasks: ['imagemin']
  5.   }
  6. },

Don’t forget to load the task by adding this:


If you are following along from part 1 you will need to adjust your Browsersync entry a bit, the following line just above the injectChanges: false line in your Browsersync entry:

watchTask: true,

You’ll also need to adjust the grunt.registerTask at the bottom of the file to:

grunt.registerTask('default', ['browserSync', 'watch']);

This way both our watcher and browsersync can properly do their jobs.

Now when we simply run:


Our watcher and browsersync both fire up ready to work! Adding an image into images/source will trigger our imagemin job and compress all the images. This is much better, but there is still a problem. It is compressing every image in the folder! It would be preferred if it only compressed newly detected images to save time. Why compress every image every time we add a new one?


We’ll use a plugin called newer to solve this issue. The image compression is a good way to showcase this, but it can be used in all type of situations.

Let’s install the newer plugin:

npm install grunt-newer --save-dev

Let’s register the plugin in our Gruntfile.js:


It’s very simple to use newer with our image watcher, simply adjust this in our watcher:

tasks: ['newer:imagemin']

Restart Grunt and try it out, it should only compress new files and leave the existing ones alone saving a lot of time.

This will conclude part 2 of the series. I plan on making more, we’ll cover SASS, a cool Drush plugin that can auto clear the caches for you when you change a template file, and testing mobile devices with Browsersync.

Free Download, 10 Step Drupal Security Audit Guide