Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gulp task pipeline to only concat if source file(s) changed

I have a gulp task that generates concatenated JS files. I am using a watch to detect changes to all the files in the project and would like the concat task to only re-concatenate the files if the source files have changed since last execution.

note: I could use more specific watch commands, but in my real production case we are generating multiple concatenanted JS files from multiple combinations of source JS files, so creating watches and tasks for each of these is much more complex

Something like this:

gulp.task('scripts', function() {
   return gulp.src('src/**/*.js')
      .pipe(cache('scripts'))
      // If no changed files in pipeline, exit pipeline, 
      // else add in all src files again
      .pipe(concat('app.js'))
      .pipe(gulp.dest('build/'));
});

I thought about using a lazypipe for the last two steps so I only run the concat and dest if there are files, but I don't know how to:

  • Run a condition based upon whether there are any files left in the pipeline still (after cache()
  • Bring back all the source files (basically reissue gulp.src() again to reprime the stream)

I know I could use gulp-remember for the second part, but in my production case it would be much cleaner to just rebuild the stream if this is possible.

Anyone done this before or have any hints for where to start?

like image 678
Allen Avatar asked Jul 16 '14 14:07

Allen


2 Answers

The code in moettinger's answer (at the time of writing) is incorrect. Here is the stream to return:

return gulp.src('src/**/*.js')
   .pipe(newer('build/app.js'))
   .pipe(concat('app.js'))
   .pipe(gulp.dest('build/'));

When testing against a single destination the newer() call must be passed a path that is relative to the current directory (or an absolute path). It cannot be a path to be interpreted against the path given in gulp.dest(). With the call newer('app.js') the newer call will always cause concat to execute because it won't find the file.

The documentation gives a similar example.

like image 107
Louis Avatar answered Oct 01 '22 10:10

Louis


The plugin gulp-newer should do the trick.

   gulp.task('scripts', function() {
   return gulp.src('src/**/*.js')
      .pipe(newer('app.js'))
      .pipe(concat('app.js'))
      .pipe(gulp.dest('build/'));
});
like image 20
moettinger Avatar answered Oct 01 '22 11:10

moettinger