9

鉴于我的 gulpfile.js 中的以下代码,每次我保存或更改文件时,任务都会运行两次而不是一次,这是为什么呢?我只想让它运行一次。

var gulp = require('gulp');

gulp.task('default', function() {

  gulp.watch('server/**/*.js', function(){
    console.log('This runs twice everytime I change/save a javascript file located at server/**/*.js');
  }); 

});

我对 grunt 和名为 grunt-contrib-watch 的插件也有同样的体验。

4

12 回答 12

13

我在 Espresso 中添加了相同的问题,您可以使用 debounceDelay 选项在 Gulp 中“修复”它,如下所示:

gulp.watch('/**/*.less', {debounceDelay: 2000}, ['less']);

这对我有用。但是将它添加到每个 gulp.watch 中会很痛苦,我不知道我们是否可以将这个选项放在全球范围内......

于 2014-08-28T12:26:12.087 回答
13

出现问题是因为您的编辑器(在本例中为 Coda 2)在保存时两次修改文件。由于 vim 如何在 save 上创建缓冲区备份,所以在 vim 中也会出现同样的问题。

vim中问题的解决方法是添加

set nowritebackup

到你的~/.vimrc文件。这会将默认保存协议更改为仅对原始文件进行一次编辑。

也就是说,默认的保存协议如下:

  1. 将缓冲区写入备份文件
  2. 删除原始文件
  3. 将备份重命名为原始文件的名称

添加set nowritebackup只是替换保存时的原始文件。该协议的存在是为了降低保存时出现 I/O 错误时数据丢失的风险。

于 2014-04-26T11:03:18.673 回答
9

这对我有用

.pipe(watch('/**/*.less', { awaitWriteFinish: true }))

https://github.com/paulmillr/chokidar#api

于 2016-02-24T23:54:47.467 回答
2

您应该能够使用gulp-batch批量更改,因为它有一个debounce选项。

像这样的东西:

gulp.src(['server/**/*.js'], batch({debounce: 50}, function(events) {
    return events
        .pipe(...); // your code here
}));
于 2014-02-06T21:12:18.677 回答
2

提示:debounce 参数仅适用于 SAME 文件/事件。如果多个事件/文件发生更改,它将无济于事。有时(例如,我将文件复制到本地服务器所服务的目录中)gulp-cached可能会有所帮助,有时排除某些文件/模式(例如 sourcemaps 文件)可能会有所帮助(使用 ! 来否定选择)。例如

gulp.watch(['js/**/*', '!js/**/*.map'])
于 2015-07-21T07:31:16.833 回答
1

一年之后 ...

使用

  • 节点0.10.25
  • 吞咽3.8.10

GazdebounceDelay选项对我没有任何改变,我也不明白如何使用 gulp-batch 回调参数:/......

为了避免在更改多个文件后连续调用任务,我使用了 oldschool setTimeout 函数:

// ...
var
SRC = ['js/*.js', '!js/*.min.js'], DEST = 'js',
processJs = function(){
    util.log('Processing: ['+ SRC.join(' | ') +']');
    var stream = gulp.src(SRC)
        .pipe(uglify())
        .pipe(concat('scripts.min.js'))
        .pipe(gulp.dest(DEST));
    return stream;
};


gulp.task('default', function(){
    var delay = 2000, timer,
        watcher = gulp.watch(
            SRC,
            // Callback triggered whatever the event type is (added / changed / deleted)
            function(event) { // .path | .type
                // If the timer was assigned a timeout id few time ago..
                // Prevent last postpone task to be run
                if(timer){
                    clearTimeout(timer);
                }
                // Postpone the task
                timer = setTimeout(
                    function(){processJs();timer=0;}
                    ,delay
                );
            }
        );
    util.log("/!\\ Watching job "+ Array(25).join('~'));
});
于 2015-02-08T20:56:55.233 回答
1

我看到了类似的问题,但这是由于在多个选项卡/窗口中打开页面引起的。

于 2014-03-20T18:52:05.267 回答
1

Had the same issue and it turns out, that gulp-sourcemaps causes it (see -> Using source maps causes task to run twice)

Get a solution with gulp-notify and the attribute onLast:

.pipe(notify({message: 'YOUR MESSAGE', onLast: true}));
于 2016-08-29T09:52:59.800 回答
0

似乎这个问题的答案是使用的编辑器 Coda 2 的一个功能。根据这里的一些评论和多个编辑器的测试,Coda 2 似乎保存了一个临时文件或类似文件,这会导致 gulp watch函数运行两次。

在使用 Coda 2 时,我还没有找到可行的解决方案,最终切换到了 Sublime Text 3。

于 2014-02-28T13:22:21.157 回答
0

我尝试了去抖动和 awaitWriteFinish。它没有用。这做到了:

const gulp = require("gulp");
const exec = require('child_process').exec;
let run = false;

gulp.task("watch", () => {
  console.log("watching ..");
  gulp.watch("**/*.js", ["browserify"]);
});

gulp.task("browserify", () => {
  if (run) { return; }
  run = true;
  console.log("calling browserify");
  exec("browserify app.js -o bundle.js");
  setTimeout(() => {
    run = false;
  }, 1000);
});
于 2017-04-08T12:47:00.670 回答
0

除了编辑器特定的解决方案之外,我还写了一个小 gulp 插件来解决这个问题。你可以gulp-debounce这样使用:

npm install --save-dev gulp-debounce

var debounce = require('gulp-debounce'),
    watch    = require('gulp-watch'),
    through  = require('through2');

gulp.watch('server/**/*.js')
.pipe(debounce({ wait: 1000 }))
.pipe(through.obj(function(vinyl) {
  console.log("this won't fire multiple times in 1000ms", vinyl.path);
});
于 2016-02-08T11:37:25.930 回答
0

我在这里写下我的经历,也许对某人有所帮助。这花了我 1 周的时间来检测。我做了所有可能的调试。删除文件,重新安装干净的节点包。删除了 Sublime 插件。报告为 Sublime github 和插件 github 页面的错误。

我的解决方案 如果打开,请关闭保管箱。我将 Dropbox 用于我的项目并在那里工作。当 Dropbox 打开时,任务会运行两次,因为 Dropbox 检测到文件更改并执行某些操作。特别是打字稿文件,我不知道为什么。

于 2016-04-05T17:53:09.850 回答