Gulp.js,保存文件时监视任务运行两次

时间:2014-02-06 16:28:02

标签: javascript gulp

鉴于我的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相同的事情。

12 个答案:

答案 0 :(得分:13)

问题出现了,因为您的编辑器(在本例中为Coda 2)在保存时将文件修改两次。 vim也会出现同样的问题,因为vim创建了buffer backups on save

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

set nowritebackup

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

换句话说,默认保存协议如下:

  1. 将缓冲区写入备份文件
  2. 删除原始文件
  3. 将备份重命名为原始文件的名称
  4. 添加set nowritebackup只是在保存时替换原始文件。此协议用于在保存时发生I / O错误时降低数据丢失的风险。

答案 1 :(得分:12)

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

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

这对我有用。但是将它添加到每个gulp.sh是一个痛苦我不知道我们是否可以将这个选项全局... ...

答案 2 :(得分:6)

这对我有用

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

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

答案 3 :(得分:2)

您应该可以使用gulp-batch批量处理更改,因为它有debounce选项。

这样的事情:

gulp.src(['server/**/*.js'], batch({debounce: 50}, function(events) {
    return events
        .pipe(...); // your code here
}));

答案 4 :(得分:2)

提示:debounce参数仅适用于SAME文件/事件。如果多个事件/文件发生变化,则无法提供帮助。有时候(例如我将文件复制到我的本地服务器所服务的目录中)gulp-cached可能有所帮助,有时排除某些文件/模式(例如源图文件)可能有所帮助(使用!来否定选择)。 e.g。

gulp.watch(['js/**/*', '!js/**/*.map'])

答案 5 :(得分:1)

我看到了类似的问题,但这是因为在多个标签/窗口中打开了页面。

答案 6 :(得分:1)

一年后......

使用

  • nodejs 0.10.25
  • gulp 3.8.10

Gaz debounceDelay选项对我没有任何改变,也没有理解如何使用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('~'));
});

答案 7 :(得分:1)

有同样的问题,事实证明,gulp-sourcemaps会导致它(参见 - > Using source maps causes task to run twice

使用gulp-notify和属性onLast:

获取解决方案
.pipe(notify({message: 'YOUR MESSAGE', onLast: true}));

答案 8 :(得分:0)

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

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

答案 9 :(得分: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);
});

答案 10 :(得分:0)

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

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

答案 11 :(得分:0)

我试过debounce和awaitWriteFinish。它没用。这样做了:

public class PaintPanel extends JPanel {    

private static final long serialVersionUID = 4267027584083413157L;

private class MouseMotionHandler implements MouseMotionListener {

    public void mouseDragged(MouseEvent e) {
        int x = e.getX();
        int y = e.getY();

        Graphics2D g2 = (Graphics2D)getGraphics();

        g2.setPaint(color);         
        g2.fillOval(x, y, size, size);
    }


    public void mouseMoved(MouseEvent e) {

    }

}

class JSliderHandler implements ChangeListener {
    @Override
    public void stateChanged(ChangeEvent e) {
        JSlider colorChange = (JSlider)e.getSource();
        if (!colorChange.getValueIsAdjusting()) {
            colVal = (int)colorChange.getValue();
            color = new Color(colVal, colVal, colVal);
            System.out.print(colVal);
        }
    }
}

class JSpinnerHandler implements ChangeListener {
    @Override
    public void stateChanged(ChangeEvent e) {
        JSpinner thickChange = (JSpinner)e.getSource();
        size = (int)thickChange.getValue();
    }
}


private Color color;
private int colVal = 0;
private int   size;


public PaintPanel() {     

    color = new Color(colVal, colVal, colVal);
    size  = 8;

    addMouseMotionListener(new MouseMotionHandler());        
}
}