gulp-newer vs gulp-changed

What're the differences between them?

gulp-newer:

gulp.src(imgSrc)
  .pipe(newer(imgDest))
  .pipe(imagemin())
  .pipe(gulp.dest(imgDest));

gulp-changed:

gulp.src(SRC)
    .pipe(changed(DEST))
    // ngmin will only get the files that
    // changed since the last time it was run
    .pipe(ngmin())
    .pipe(gulp.dest(DEST));

It seems gulp-changed is more powerful, because it provides an option

hasChanged: changed.compareLastModifiedTime

Solution 1:

I hope it's not too late to answer this question. I have had to evaluated both of them at a source-code level for a recent project, and here is my take.

gulp-newer

At the core, this plugin compares the source and dest file's modified time (see node API) to decide whether the source file is newer than the dest file or if there is no dest file at all. Here is the related code in the plugin:

var newer = !destFileStats || srcFile.stat.mtime > destFileStats.mtime;

gulp-changed

This plugin by default also uses a file's modified time to decide which to pass through the stream

function compareLastModifiedTime(stream, cb, sourceFile, targetPath) {}

but it goes one step further by offering an option to compare the file's content SHA1 hash:

function compareSha1Digest(stream, cb, sourceFile, targetPath) {}

This information is nicely documented.

Conclusion

So theoretically speaking, if you use gulp-changed's default hasChanged: changed.compareLastModifiedTime, each plugin is relatively as fast as the other. If you use gulp-changed's hasChanged: changed.compareSha1Digest, it's reasonable to expect gulp-changed to be a bit slower because it does create a SHA1 hash of the file content. I didn't benchmark but I'm also interested in seeing some number.

Which to choose

gulp-changed, purely because of the developer behind it (sindresorhus). If one day this awesome man decides that he will stop supporting his gulp plugins, I think I will stop using gulp altogether.

Joking aside, though, gulp-changed's source code is gulp-y, while gulp-newer's source reads pretty much like just another node module's source with lots of promises. So another +1 for gulp-changed :)

HUGE EDIT

Gulp-changed only works with 1:1 source:dest mapping. If you need many:1, e.g. when using with gulp concat, choose gulp-newer instead.

Solution 2:

May I suggest gulp-newy in which you can manipulate the path and filename in your own function. Then, just use the function as the callback to the newy(). This gives you complete control of the files you would like to compare.

This will allow 1:1 or many to 1 compares.

newy(function(projectDir, srcFile, absSrcFile) {
  // do whatever you want to here. 
  // construct your absolute path, change filename suffix, etc. 
  // then return /foo/bar/filename.suffix as the file to compare against
}

enter image description here

Solution 3:

In order to answer this question you will have to compare both plugins source code.

Seems that gulp-changed has more options as you have said, more used (it was downloading more time) and more contributors, thus, it could be more updated and refactored, as it was being used more.

Something that can make a difference, due to them documentation.

On the example, for gulp-newer, its used like this:

gulp.task('default', function() {
  gulp.watch(imgSrc, ['images']);
});

Thus, seems that once this task is running, it will only notice files that are changing while you are using this plugin.

On gulp-changed, they say: "will only get the files that changed since the last time it was run". So, and I didnt try this on a working example, that gulp-changed proccess all files and then only the ones that have been changed since last execution, so seems it will always "look" at all files and internally (md5 hash? no clue, didnt check the source) decide whereas a file has changed since last execution. Do not need a watcher for that.

All this, was only reading their official documentation.

A "on the wild test" would be very welcomed !