I have tried to use Prepros and one feature that I like is its image optimization. This feature reduces the byte size of of the image and this means faster web page loading. But Grunt is the workflow management I am using. Good thing is Grunt has this Imagemin plugin which can also optimize images (jpeg, png and gif). Lets take a look on how to setup and use this plugin to our workflow. My operating system is Windows. Therefore, the shell commands, output, etc. that will be shown here are for Windows.
File structure
We'll use this project folder structure:
Where:
img_src = all image files (jpeg, png and gif) stored here will be the source of imagemin
img_dest = optimized image files processed by imagemin will be saved in this folder
Lets create two empty text files labeled as "package.json" and "gruntfile.js":
Setup Imagemin
Populate "package.json" with these codes:
{
"name": "sample_project",
"description": "Sample imagemin project",
"version": "0.0.1",
"author": "Your name",
"homepage": "http://www.webfoobar.com",
"dependencies": {
"grunt": "~0.4.5",
"grunt-contrib-imagemin": "~1.0.0",
"grunt-contrib-watch": "~0.6.1"
}
}
At your command prompt, execute:
npm install
As output, you should see something like this (by the way, I am using Git's cygwin here):
We will going to use pngquant to optimize png image files, mozjpeg for jpeg and gifsicle for gif.
To install pngquant, execute the following command at your terminal:
npm install imagemin-pngquant
Terminal output:
To install mozjpeg, execute the following command at your terminal:
npm install imagemin-mozjpeg
Terminal output:
And to install gifsicle, execute the following command at your terminal:
npm install imagemin-gifsicle
Terminal output:
You may be asking, why we did not just add imagemin-pngquant, imagemin-mozjpeg and imagemin-gifsicle as dependencies at our "package.json" file and execute "npm install" to install all plugins in one command. I have already tried but I got this error:
Note: if ever one or all the image tools software failed to install, temporarily disable the anti-virus and execute the commands again to re-install.
Grunt tasks
Open our "gruntfile.js" and populate it with these codes:
var pngquant = require('imagemin-pngquant');
var mozjpeg = require('imagemin-mozjpeg');
var gifsicle = require('imagemin-gifsicle');
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-imagemin');
grunt.initConfig({
imagemin:{
target: {
options: {
optimizationLevel: 3,
progressive: true,
use: [pngquant(), mozjpeg(), gifsicle()]
}, // options
files: [{
expand: true,
cwd: 'img_src/',
src: ['**/*.{png,jpg,jpeg,gif}'],
dest: 'img_dest/'
}] // files
} // target
}, // imagemin
watch: {
imageopti: {
files: ['img_src/*.*'],
tasks: ['imagemin']
} // imageopti
} // watch
}); // initConfig
grunt.registerTask('default', 'watch');
} // exports
Execute the following command at your terminal:
grunt
You should see something like this at your terminal:
Grunt is now waiting for any changes (file edit or file add) in our "img_src" folder. If we add image files in this folder, we should see something like this at our terminal:
Grunt will automatically optimize the image files (*.png, *.jpg, *.jpeg and *.gif) inside "img_src" and save the optimized image files at "img_dest" folder.
Comments
You're welcome, glad be of…
You're welcome, glad be of help.
Issue with grunt
Hi!
Thanks for this tutorial, and also for "Using SASS in Bootstrap Drupal theme".
I have setup imagemin following the steps above, but when I start grunt, the following error message is displayed:
/home/alien/www/www-gorj/sites/all/themes/gjtheme/node_modules/imagemin-pngquant/index.js:2
const execBuffer = require('exec-buffer');
^^^^^
Loading "gruntfile.js" tasks...ERROR
>> SyntaxError: Use of const in strict mode.
Warning: Task "default" not found. Use --force to continue.
Aborted due to warnings.
Can you help me with this?
Thank you!
[email protected]
Hi,
You're welcome!
That's new, I haven't encountered that error. I checked my "node_modules/imagemin-pngquant/index.js" line 1 to 5:
'use strict';
var spawn = require('child_process').spawn;
var isPng = require('is-png');
var pngquant = require('pngquant-bin');
var through = require('through2');
Your's different. My imagemin-pngquant version is 4.2.0. Please try installing that version:
npm install [email protected]
Solved
Hi!
Thank you! That solved my problem. I was using the latest versions of imagemin-pngquant, imagemin-mozjpeg & imagemin-gifsicle. Hence the error.
Starting from your fix, I tried other versions for those libraries and it turned out that the latest versions that work in this context are:
[email protected]
[email protected]
[email protected]
Also, I noticed that the script is running the imagemin task for all the images in the source folder everytime you add a new image. I solved this by installing grunt-newer
sudo npm install grunt-newer --save-dev
Based on your script, my new gruntfile.js looks like this:
var pngquant = require('imagemin-pngquant');
var mozjpeg = require('imagemin-mozjpeg');
var gifsicle = require('imagemin-gifsicle');
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-compass');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-imagemin');
grunt.loadNpmTasks('grunt-newer');
grunt.initConfig({
uglify: {
js_dev: {
options: {
preserveComments: 'all',
beautify: {
width: 80,
beautify: true
} // beautify
}, // options
files: {
'js/scripts.js': [
'bootstrap/javascripts/bootstrap/affix.js',
'bootstrap/javascripts/bootstrap/alert.js',
'bootstrap/javascripts/bootstrap/button.js',
'bootstrap/javascripts/bootstrap/carousel.js',
'bootstrap/javascripts/bootstrap/collapse.js',
'bootstrap/javascripts/bootstrap/dropdown.js',
'bootstrap/javascripts/bootstrap/modal.js',
'bootstrap/javascripts/bootstrap/tooltip.js',
'bootstrap/javascripts/bootstrap/popover.js',
'bootstrap/javascripts/bootstrap/scrollspy.js',
'bootstrap/javascripts/bootstrap/tab.js',
'bootstrap/javascripts/bootstrap/transition.js',
'assets/js/*.js'
]
} // files
}, // js_dev
js_prod: {
files: {
'js/scripts.js': [
'bootstrap/javascripts/bootstrap/affix.js',
'bootstrap/javascripts/bootstrap/alert.js',
'bootstrap/javascripts/bootstrap/button.js',
'bootstrap/javascripts/bootstrap/carousel.js',
'bootstrap/javascripts/bootstrap/collapse.js',
'bootstrap/javascripts/bootstrap/dropdown.js',
'bootstrap/javascripts/bootstrap/modal.js',
'bootstrap/javascripts/bootstrap/tooltip.js',
'bootstrap/javascripts/bootstrap/popover.js',
'bootstrap/javascripts/bootstrap/scrollspy.js',
'bootstrap/javascripts/bootstrap/tab.js',
'bootstrap/javascripts/bootstrap/transition.js',
'assets/js/*.js'
]
} // files
} // js_prod
}, // uglify
compass: {
prod: {
options: {
config: 'config.rb',
environment: 'production'
} // options
}, // prod
dev: {
options: {
config: 'config.rb'
} // options
} // dev
}, // compass
imagemin: {
target: {
options: {
use: [pngquant(), mozjpeg(), gifsicle()],
},
files: [{
expand: true,
cwd: 'assets/images/',
src: ['**/*.{png,jpg,jpeg,gif}'],
dest: 'img/'
}] // files
} // target
}, // imagemin
watch: {
sass: {
files: ['assets/sass/*.scss'],
tasks: ['compass:dev']
}, // sass
javascripts: {
files: ['assets/js/*.js'], // We only need to watch the custom js
tasks: ['uglify:js_dev']
}, // javascripts
imageopti: {
files: ['assets/images/*.*'],
tasks: ['newer:imagemin']
} // imageopti
} // watch
}); // initConfig
grunt.registerTask('default', 'watch');
grunt.registerTask('prod', ['uglify:js_prod', 'compass:prod', 'imagemin']);
} // exports
I shared this in case you find it useful.
Thanks again for your tutorial! It is really helpfull!
Hi, that's good news! Glad…
Hi, that's good news! Glad to be of help. Thank you also for sharing your experiments.
Fatal error: Cannot read property 'contents' of undefined
The solution for "Fatal error: Cannot read property 'contents' of undefined" error is to update your grunt-contrib-imagemin to version 1.0.0. Open your package.json and have the following script:
{
"name": "sample_project",
"description": "Sample imagemin project",
"version": "0.0.1",
"author": "Your name",
"homepage": "http://www.webfoobar.com",
"dependencies": {
"grunt": "~0.4.5",
"grunt-contrib-imagemin": "~1.0.0",
"grunt-contrib-watch": "~0.6.1"
}
}
And run:
npm install
Thanks
Thsi worked for me.....Appreciate the effort