gulp-changed 未过滤掉未更改的文件

gulp-changed isn't filtering out non-changed files

我正在尝试使用 gulp-changed 来防止在未更改的文件上发生耗时的任务。我的 gulpfile.js 设置如下:

gulp.task("min:css", function () {
    return gulp.src([paths.css, "!" + paths.minCss])
        .pipe(changed("."))
        .pipe(concat(paths.concatCssDest))
        .pipe(autoprefixer({ browsers: ['> 5%'] }))  //support browsers with >5% market share
        .pipe(cssmin())
        .pipe(gulp.dest("."));
});

然而每次我看到的都是 运行:

[11:15:02] Starting 'min:js'...
[11:15:02] Starting 'min:css'...
[11:15:02] Finished 'min:css' after 79 ms
Process terminated with code 0.
[11:15:02] Finished 'min:js' after 121 ms
[11:15:02] Starting 'min'...
[11:15:02] Finished 'min' after 12 μs

有什么原因 gulp-changed 没有过滤这些未更改的文件?

首先 你似乎误解了 gulp-changed 的实际作用。 gulp-changed 无法阻止来自 运行 的任务。这意味着这两行:

[11:15:02] Starting 'min:css'...
[11:15:02] Finished 'min:css' after 79 ms

将出现在 gulp 的日志输出中 即使没有单个 CSS 文件已更改gulp-changed 只是从流中删除未更改的文件,这样它们就不会到达后面的 pipe() 阶段。文件仍在处理,直到达到 changed()

(巧合的是,我昨天刚刚写了一个答案,它也涉及 gulp-changed 并将其操作模式与 gulp.watch()gulp-watch 进行了对比。。)

其次gulp-changed如何知道一个文件是否改变了?它将源文件与目标文件进行比较。如果目标文件比源文件旧,则源文件必须已更改。

要使其工作,gulp-changed 必须能够从源文件映射到目标文件。但是,您有多个源文件和一个目标文件(您的串联文件)。这意味着您必须提供自定义 hasChanged handler 以从源文件映射到目标文件。

第三,即使你做了所有这些,你的任务仍然不可能按照你想要的方式进行。由于 gulp-changed 仅让那些已更改的文件通过,因此只有那些文件最终会出现在您的串联输出文件中。

假设您想将 foo.cssbar.css 连接成 all.css。这在第一次时会很好用。但是,如果您随后更改 bar.css,则 bar.css 将最终变为 all.css

由于您总是需要所有 CSS 文件作为输入,因此您 不能gulp-changedgulp-concat 结合使用。

话虽这么说,如果您想在从 gulp.watch() 调用时加快 min:css 任务,您可以按照 official Gulp.js incremental rebuilding recipe:

gulp.task("min:css", function () {
  return gulp.src([paths.css, "!" + paths.minCss])
    .pipe(cached('cssCache'))
    .pipe(autoprefixer({ browsers: ['> 5%'] }))
    .pipe(cssmin())
    .pipe(remember('cssCache'))
    .pipe(concat(paths.concatCssDest))
    .pipe(gulp.dest("."));
});