javascriptgulpgulp-imageminminimatchgulp-if

Gulpfile task to copy files should optimize images if there are any


In my gulpfile I'm copying multiple globs of files (various formats) and if any of these globs contains an image I'd like to optimize it with gulp-imagemin.

Problem is gulp-imagemin expects only images otherwise throws unsupported image in the log, so if I were to pass in the entire glob it would throw many errors and I want to avoid that. I've tried gulp-if to filter the glob, while it works as a filter and prevents these errors, it seems to always pass at least once even if no images are present. For example this will still call the imagemin() once even though there are no png files whatsoever:

gulp.task('test:imagemin', function () {
  return gulp.src('*.nothing')
    .pipe(gulpif('*.png', imagemin({ verbose: true })));
});

This will log "Minified 0 images" and since in my real scenario I'm passing in dozens of globs without images my log gets spammed with it. If I set gulpif condition to static false, it won't call imagemin at all, so it must be something with this condition not being false when it's supposed to?

How do I not call imagemin() at all if glob doesn't contain file of a certain type?


Solution

  • Turns out problem was gulp-if resolving action before the condition. Condition needs to be put outside the vinyl stream. So first I synced the glob to get the files, then I determined whether there are any supported images and saved this to a bool. Then when calling gulp-if I had to condition this bool and nest in another gulp-if to filter.

    function copyFilesPipeline(assetGroup) {
      var containsImages = glob.sync(assetGroup.inputPaths).some(function (inputPath) {
        var ext = path.extname(inputPath).toLowerCase();
        return [".gif", ".jpg", ".png", ".svg"].includes(ext);
      });
    
      return gulp.src(assetGroup.inputPaths)
        .pipe(makeFilesLowercase())
        .pipe(gulpif(containsImages, gulpif('**/*.{gif,jpg,png,svg}', imagemin({ verbose: true }))))
        .pipe(newer(assetGroup.outputDir))
        .pipe(gulp.dest(assetGroup.outputDir));
    }