Skip to content

Commit

Permalink
Cache images
Browse files Browse the repository at this point in the history
Closes #40
  • Loading branch information
e7h4n authored and sindresorhus committed Aug 11, 2013
1 parent a310571 commit f30029b
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 3 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1,3 +1,4 @@
node_modules
npm-debug.log
tmp
tmp-cache/
2 changes: 1 addition & 1 deletion Gruntfile.js
Expand Up @@ -34,7 +34,7 @@ module.exports = function (grunt) {
}
},
nodeunit: {
tasks: ['test/*_test.js']
tests: ['test/*_test.js']
}
});

Expand Down
36 changes: 34 additions & 2 deletions tasks/imagemin.js
Expand Up @@ -15,6 +15,23 @@ module.exports = function (grunt) {
var filesize = require('filesize');
var optipngPath = require('optipng-bin').path;
var jpegtranPath = require('jpegtran-bin').path;
var crypto = require('crypto');
var os = require('os');

var cacheDirectory = (os.tmpdir || function() {
if (process.platform === 'win32') {
return process.env.TEMP || process.env.TMP || (process.env.SystemRoot || process.env.windir) + '\\temp';
} else {
return process.env.TMPDIR || process.env.TMP || process.env.TEMP || '/tmp';
}
})();
cacheDirectory = path.join(cacheDirectory, 'grunt-contrib-imagemin.cache');

function hashFile(filePath) {
var content = grunt.file.read(filePath);

return crypto.createHash('sha1').update(content).digest('hex');
}

grunt.registerMultiTask('imagemin', 'Minify PNG and JPEG images', function () {
var done = this.async();
Expand Down Expand Up @@ -49,6 +66,7 @@ module.exports = function (grunt) {
function optimize(src, dest, next) {
var cp;
var originalSize = fs.statSync(src).size;
var cachePath = path.join(cacheDirectory, hashFile(src));

function processed(err, result, code) {
var saved, savedMsg;
Expand All @@ -60,19 +78,33 @@ module.exports = function (grunt) {
saved = originalSize - fs.statSync(dest).size;
totalSaved += saved;

if (result.stderr.indexOf('already optimized') !== -1 || saved < 10) {
if (result && (result.stderr.indexOf('already optimized') !== -1 || saved < 10)) {
savedMsg = 'already optimized';
} else {
savedMsg = 'saved ' + filesize(saved);
}

if (!grunt.file.exists(cachePath)) {
grunt.file.copy(dest, cachePath);

if (grunt.option('verbose')) {
grunt.log.writeln('[Caching] ' + cachePath + ' <- ' + src);
}
}

grunt.log.writeln('✔ '.green + src + (' (' + savedMsg + ')').grey);
next();
}

grunt.file.mkdir(path.dirname(dest));

if (path.extname(src).toLowerCase() === '.png') {
if (grunt.file.exists(cachePath)) {
if (grunt.option('verbose')) {
grunt.log.writeln('[Cached] ' + cachePath + ' -> ' + src);
}
grunt.file.copy(cachePath, dest);
processed();
} else if (path.extname(src).toLowerCase() === '.png') {
// OptiPNG can't overwrite without creating a backup file
// https://sourceforge.net/tracker/?func=detail&aid=3607244&group_id=151404&atid=780913
if (dest !== src && grunt.file.exists(dest)) {
Expand Down
28 changes: 28 additions & 0 deletions test/imagemin_test.js
@@ -1,6 +1,18 @@
'use strict';
var grunt = require('grunt');
var fs = require('fs');
var path = require('path');
var crypto = require('crypto');
var os = require('os');

var cacheDirectory = (os.tmpdir || function() {
if (process.platform === 'win32') {
return process.env.TEMP || process.env.TMP || (process.env.SystemRoot || process.env.windir) + '\\temp';
} else {
return process.env.TMPDIR || process.env.TMP || process.env.TEMP || '/tmp';
}
})();
cacheDirectory = path.join(cacheDirectory, 'grunt-contrib-imagemin.cache');

exports.imagemin = {
minifyPng: function (test) {
Expand All @@ -21,6 +33,14 @@ exports.imagemin = {

test.done();
},
cachePng: function (test) {
test.expect(1);

var original = crypto.createHash('sha1').update(grunt.file.read('test/fixtures/test.png')).digest('hex');
test.ok(fs.existsSync(path.join(cacheDirectory, original)), 'should cached PNG images');

test.done();
},
minifyJpg: function (test) {
test.expect(1);

Expand All @@ -37,6 +57,14 @@ exports.imagemin = {
var original = fs.statSync('test/fixtures/test-uppercase.JPG').size;
test.ok(actual < original, 'should minify uppercase extension JPG images');

test.done();
},
cacheJpg: function (test) {
test.expect(1);

var original = crypto.createHash('sha1').update(grunt.file.read('test/fixtures/test.jpg')).digest('hex');
test.ok(fs.existsSync(path.join(cacheDirectory, original)), 'should cached JPG images');

test.done();
}
};

0 comments on commit f30029b

Please sign in to comment.