I'd like to use gulp to generate a bunch of different image sizes and optimize them at the same time. I think there are two approaches to this problem:
The first is that you could create n different tasks for each size, then create a master task that calls each resize task. The master task might look something like:
gulp.task('resize_images',['resize_100','resize_300','resize_800','resize_1000']);
This seems ok, and you'd get good parallelization, but there is a lot of duplicated code for each task which means maintaining it could be a nightmare if the list of sizes grows large enough.
The other idea I'd had was to create a single task, but use a for loop within it to iterate over each size. Like so:
var gulp = require('gulp');
var imageminWebp = require('imagemin-webp');
var imageResize = require('gulp-image-resize');
var notify = require('gulp-notify');
var os = require('os');
var parallel = require('concurrent-transform');
var pipes = require('gulp-pipes');
gulp.task('resize_images', function() {
var sizes = [100,300,800,1000,2000];
var stream;
for (size in sizes) {
stream = gulp.src('images/master/**/*.{jpg,png,tiff}')
.pipe(parallel(
imageResize({
width: sizes[size],
height: sizes[size],
upscale: false
}),
os.cpus().length
))
.pipe(pipes.image.optimize())
.pipe(gulp.dest('images/derivative/' + sizes[size] + '/'))
.pipe(imageminWebp({quality: 75})())
.pipe(gulp.dest('images/derivative/' + sizes[size] + '/'))
}
return stream;
});
This seems ok, but doesn't feel gulp-y for some reason. For example, notifications are weird with the solution above - I'd like to notify when each is size is done processing, which I get for free with the single master task. Is there a better way to accomplish what I'm trying to do?
Remember: Gulp is just JavaScript.
There's nothing magical about gulp.task
. You don't have to put everything in a Gulpfile inside of a task. Tasks are just functions.
You can leverage this fact and dynamically generate a bunch of tasks based on certain parameters, so you don't have duplicated code all over the place. In your case you can generate one task per image size that you want to create:
var resizeImageTasks = [];
[100,300,800,1000,2000].forEach(function(size) {
var resizeImageTask = 'resize_' + size;
gulp.task(resizeImageTask, function() {
return gulp.src('images/master/**/*.{jpg,png,tiff}')
.pipe(imageResize({
width: size,
height: size,
upscale: false
}))
.pipe(pipes.image.optimize())
.pipe(gulp.dest('images/derivative/' + size + '/'))
.pipe(imageminWebp({quality: 75})())
.pipe(gulp.dest('images/derivative/' + size + '/'))
});
resizeImageTasks.push(resizeImageTask);
});
gulp.task('resize_images', resizeImageTasks);
For Gulp 4:
var imagemin = require('gulp-imagemin');
var imageResize = require('gulp-image-resize');
var rename = require("gulp-rename");
function images(cb) {
[100, 300, 800, 1000, 2000].forEach(function (size) {
gulp.src('src/images/**/*.{jpg,jpeg,png}')
.pipe(imageResize({ width: size }))
.pipe(rename(function (path) { path.basename = `${path.basename}@${size}w`; }))
.pipe(imagemin())
.pipe(gulp.dest('dist/images'))
});
cb();
}
The callback is used to signal async completion (required by Gulp 4).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With