向 运行 gulp 手表添加条件

Add a condition to run a gulp watch

我有一个 gulp 监视任务如下:

gulp.task("watch", () => {
  const watch = {
    'dev': [src_folder + '**/*.njk', src_js_folder + '**/*.js'],
    'css': [src_sass_folder + '**/*.scss']
  }
  gulp.watch(watch.dev, gulp.series("dev")).on("change", browserSync.reload);
  gulp.watch(watch.css, gulp.series("sass"));

});

gulp.task("dev", gulp.series("merge-json", "nunjucks", "sass", "js"));

因此,当 *.sass 文件发生任何变化时,sass 任务将 运行,当 *.js and/or *.njk 发生变化时] 归档任务 dev 将 运行。

我遇到的问题是,当 *.sass*.js and/or *.njk 同时发生变化时,sass 任务在这种情况下将 运行 两次。

gulp.watch(watch.dev, gulp.series("dev")).on("change", browserSync.reload); 已经是 运行 时,如何跳过 gulp.watch(watch.css, gulp.series("sass"));

假设这是由于文件快速更改造成的,设置监视 delay 选项可能会有所帮助:

gulp.watch(watch.dev, { delay: 500 }, gulp.series("dev"))

如果这没有帮助,您可能需要想办法消除事件的反弹。有一个名为 gulp-debounce 的旧软件包似乎实现了这一点,但无人维护,因此可能不兼容,但查看其源代码可能会提供一些见解。

问题

sass 任务在 运行 执行 watch 任务时重复执行,因为在您共享的代码中,您有效地将 sass 任务定义为运行两次。

gulp.task("watch", () => {
    const watch = {
        'dev': [src_folder + '**/*.njk', src_js_folder + '**/*.js'],
        'css': [src_sass_folder + '**/*.scss']
    }

    // 1st execution > The `dev` task is defined into the `gulp.series()` as part
    // of the combined tasks to run for this watcher, and, as `dev` contains the
    // `sass` task in it this will run it the first time.
    gulp.watch(watch.dev, gulp.series("dev")).on("change", browserSync.reload);
    
    // 2nd execution > This watcher have the `sass` task defined into the
    // `gulp.series()` as part of the combined tasks to run, this will run
    // the second time
    gulp.watch(watch.css, gulp.series("sass"));
});

// The `dev` task contains the`sass` task into the `gulp.series()` as part
// of the combined tasks to run
gulp.task("dev", gulp.series("merge-json", "nunjucks", "sass", "js"));

因此,每次运行 gulp dev sass任务只会执行一次,而每次运行 gulp watch sass任务将被执行两次。

解决方案

要解决这个问题,您或许可以用稍微不同的方式重新排序执行。以下是一些可能的解决方案的想法。

- 可能的解决方案 1

const paths = {
    njk: src_folder + '**/*.njk',
    js: src_js_folder + '**/*.js',
    sass: src_sass_folder + '**/*.scss'
}

gulp.task("watch", () => {
    gulp.watch([
            paths.njk,
            paths.js,
            paths.sass
        ],
        gulp.series("dev")
    ).on("change", browserSync.reload);
});

gulp.task("dev", gulp.series("merge-json", "nunjucks", "sass", "js"));

在此示例中,我们将 sass 任务定义为 dev 任务的 gulp.series 中定义的 运行 组合任务的一部分。这将允许我们 运行 gulp dev 并且只执行所有这些任务一次。它还将允许我们 运行 gulp watch 并在每次更新 paths 中定义的文件时仅执行一次为 dev 任务定义的任务。

- 可能的解决方案 2

const paths = {
    njk: src_folder + '**/*.njk',
    js: src_js_folder + '**/*.js',
    sass: src_sass_folder + '**/*.scss'
}

gulp.task("watch", () => {
    gulp.watch([
            paths.njk,
            paths.js,
        ],
        gulp.series("dev")
    ).on("change", browserSync.reload);
    gulp.watch(paths.sass, gulp.series("sass");
});

gulp.task("dev", gulp.series("merge-json", "nunjucks", "js"));

gulp.task("another_extra_task", gulp.series("dev", "sass"));

在此示例中,我们将 sass 任务从组合任务中删除为 运行 以用于 dev 任务,此外,我们定义了 another_extra_task 任务正在组合 devsass 任务。这将允许我们 运行 gulp another_extra_task 并执行为 devsass 任务定义的所有组合任务,而且,它还将允许我们 运行 gulp watch 无需重复执行 sass 任务,因为在第一个观察者中我们执行 dev 任务,其中 sass 任务不再定义,我们只需执行它第二个观察者。

结论

由于任务的定义取决于每个特定的用例,我建议您尝试以更细粒度的方式重新排序它们的执行。请参阅以下参考资料,其中解释了如何避免重复任务 https://gulpjs.com/docs/en/api/series#avoid-duplicating-tasks

我希望这些可能的解决方案能帮助您理解您在共享的代码中遇到的问题!