Gulp.js, the scan task is executed twice when saving files

Given the following code snippet from my gulpfile.js, every time I save or modify a file, the task runs twice, not once, why? I just want it to run once.

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'); }); }); 

I also experienced the same thing with grunt and a plugin called grunt-contrib-watch.

+7
javascript gulp
source share
12 answers

It seems that the answer to this question is a feature of the editor that was used, Coda 2. Based on some comments here and testing several editors, it seems that Coda 2 saves a temporary file or similar, and this calls the gulp clock function will be executed twice.

I did not find a viable solution for this when using Coda 2, as a result of which I switched to Sublime Text 3.

0
source share

The problem arises because your editor, in this case Coda 2, modifies the file twice when saved. The same problem occurs in vim because vim backs up the buffer when it is saved .

The solution to the problem in vim is to add

 set nowritebackup 

into your ~/.vimrc file. This changes the default save protocol to only make one edit to the source file.

In other words, the default save protocol is as follows:

  • Writing a buffer to a backup file
  • Delete source file
  • Rename the backup to the source file name

And adding set nowritebackup just replaces the original file when saving. This protocol exists to reduce the risk of data loss in the event of an I / O error during storage.

+13
source share

I will add the same problem to Espresso, and you can "fix" it in Gulp using the debounceDelay option as follows:

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

This is a trick for me. But it’s a pain to add it to every gulp.watch. I don’t know if we can put this globaly option ...

+12
source share

It worked for me

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

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

+4
source share

You can use gulp-batch to make changes to the package because it has a debounce parameter.

Something like that:

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

Hint: The debounce parameter only works for a SAME file / event. If several events / files change, this will not help. Sometimes (for example, I copied files to a directory served by my local server) gulp-cached can help, sometimes excluding certain files / templates (for example, sourcemaps files) can help (use! To deselect). eg.

 gulp.watch(['js/**/*', '!js/**/*.map']) 
+2
source share

I saw a similar problem, but it was caused by the fact that the page is open in several tabs / windows.

+1
source share

In a year...

Using

  • nodejs 0.10.25
  • gulp 3.8.10

The Gaz debounceDelay function did not change anything for me, and I did not understand how to use the gulp -Batch callback argument :/ ...

To avoid calling tasks with a sequence after several files have been changed, I used the oldschool setTimeout function:

 // ... 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('~')); }); 
+1
source share

It has the same problem, and it turns out that gulp -sourcemaps calls it (see → Using source maps makes the task run twice )

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

 .pipe(notify({message: 'YOUR MESSAGE', onLast: true})); 
+1
source share

In addition to special solutions for the editor, I wrote a small gulp plugin that solves the problem. You can use gulp-debounce like this:

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); }); 
0
source share

I am writing my experience here, perhaps helping someone. It cost me 1 week to discover. I did my best debugging. Files removed, clean node packages reinstalled. Removed Sublime plugins. Reported as a bug for Sublime github and github page plugins.

My solution Close dropbox if open. I use Dropbox for my project and work there. When Dropbox is open, tasks are run twice because Dropbox detects a file change and does something. Specially Typescript files, I do not know why.

0
source share

I tried debounce and was waiting for WriteFinish. This did not work. It happened:

 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); }); 
0
source share

All Articles