8

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?

Allen
  • 3,134
  • 5
  • 29
  • 49
  • Have you taken a look at [gulp-changed](https://www.npmjs.org/package/gulp-changed/)? – Josh Clayton Jul 16 '14 at 20:11
  • @JoshClayton I did checkout gulp-changed and it looks like it would behave the same as gulp-cached with respect to this issue. (ie. it would only pass through input files in the stream that actually need to be processed). I don't see that it would solve the issue about exiting or adding all src files again. – Allen Jul 17 '14 at 00:58

3 Answers3

3

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.

Community
  • 1
  • 1
Louis
  • 146,715
  • 28
  • 274
  • 320
1

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/'));
});
moettinger
  • 4,949
  • 2
  • 15
  • 20
0

Although this is an old question i thought i would just add to the gulp-newer information. Gulp-newer detects changes based on the timestamp of the files, if a file is deleted the gulp-newer does not pick this change up.

due to this i am looking at going down the caching route rather than newer as i need my main concated file to be generated if one of the css files is deleted or changed but gulp newer does not support all of this.

lilpug
  • 141
  • 1
  • 6