Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Gulp, how do I only run a task on one file if any of multiple files are newer?

Tags:

gulp

I'm probably trying to make gulp do something that's not idiomatic, but here goes. I want my build task to only run if the source files are newer than the output file.

In gulp, it seems standard practice to create a build task that always runs, and then set up a watch task to only run that build task when certain files change. That's okay, but it means that you always build on the first run.

So, is it possible to do what I want? Here's what I've got so far (newer is gulp-newer):

gulp.task('build_lib', function() {

return gulp.src(["app/**/*.ts"])
    .pipe(newer("out/outputLib.js")) //are any of these files newer than the output?

 ** NEED SOMETHING HERE **
   how do I say, "If I got _any_ files from the step before, replace all of them with a single hardcoded file "app/scripts/LibSource.ts" "?

    .pipe(typescript({
        declaration: true,
        sourcemap: true,
        emitError: false,
        safe: true,
        target: "ES5",
        out: "outputLib.js"
    }))
    .pipe(gulp.dest('out/'))

});

I tried using gulpif, but it doesn't seem to work if there are no files going into it to begin with.

    .pipe(gulpif(are_there_any_files_at_all,
        gulp.src(["app/scripts/LibSource.ts"])))

However, my condition function isn't even called because there are no files on which to call it. gulpif calls the truthy stream in this case, so LibSource gets added to my stream, which isn't what I want.

Maybe doing all of this in a single stream really isn't the right call, since the only reason I'm passing those files through the "gulp-newer" filter is to see if any of them is newer. I'm then discarding them and replacing them with another file. My question still stands though.

like image 342
Taytay Avatar asked Jun 10 '14 11:06

Taytay


2 Answers

You can write your own through/transform stream to handle the condition like so:

// Additional core libs needed below
var path = require('path');
var fs = require('fs');
// Additional npm libs
var newer = require('gulp-newer');
var through = require('through');
var File = require('vinyl');

gulp.task('build_lib', function() {
  return gulp.src(["app/**/*.ts"])
    .pipe(newer("out/outputLib.js"))
    .pipe(through(function(file) {
      // If any files get through newer, just return the one entry
      var libsrcpath = path.resolve('app', 'scripts', 'LibSource.ts');
      // Pass libsrc through the stream
      this.queue(new File({
        base: path.dirname(libsrcpath),
        path: libsrcpath,
        contents: new Buffer(fs.readFileSync(libsrcpath))
      }));
      // Then end this stream by passing null to queue
      // this will ignore any other additional files
      this.queue(null);
    }))
    .pipe(typescript({
      declaration: true,
      sourcemap: true,
      emitError: true,
      safe: true,
      target: "ES5",
      out: "outputLib.js"
    }))
    .pipe(gulp.dest('out/'));
});
like image 69
Kyle Robinson Young Avatar answered Oct 14 '22 02:10

Kyle Robinson Young


I know like, this question was posted over 4 years ago, however; I am sure this problem crosses the path of everyone, and although I think I understand the question that is being asked, I feel that there is an easier way to perform this task, off which, I posted a similar question recently on stackoverflow at New to GULP - Is it necessary to copy all files from src directory to dist directory for a project? It uses gulp-changed, and for me, it worked like a charm, so for others who may look at this post for similar reasons, have a look at my post and see if it is what you are looking for. Kind Regards

like image 22
Colin Nolan Avatar answered Oct 14 '22 03:10

Colin Nolan