18

I am trying to get watchify working with Gulp but it seems that the 'update' event is never fired.

Here's my gulpfile.js:

"use strict";

var gulp = require('gulp');
var browserify = require('browserify');
var source = require("vinyl-source-stream");
var watchify = require('watchify');

var bundler = watchify(browserify({entries: ['./client/app/app.js'], cache: {}, packageCache: {}, fullPaths: true}));

gulp.task('js', bundle); 

function bundle() {
    console.log('bundle');
    return bundler.bundle()
    .pipe(source('bundle.js'))
    .pipe(gulp.dest('./dist'));
}

// this is never fired!
bundler.on('update', bundle);

However, when I explicitly watch the files without watchify it works:

"use strict";

var gulp = require('gulp');
var browserify = require('browserify');
var source = require("vinyl-source-stream");
var watchify = require('watchify');

function bundle() {
    console.log('bundle');
    return browserify('./client/app/app.js')
    .bundle()
    .pipe(source('bundle.js'))
    .pipe(gulp.dest('./dist/'));
}

gulp.task('browserify', bundle);

gulp.task('js', function() {
    bundle();
    gulp.watch(['client/**/*.js'], ['browserify']);
});

I've tried numerous examples but with watchify the bundle never updates.

I'm running Gulp inside a Vagrant VM, host is OSX Yosemite, guest is Ubuntu 14.04.

Any help is greatly appreciated!

loganfsmyth
  • 156,129
  • 30
  • 331
  • 251
Danny Moerkerke
  • 452
  • 4
  • 18

4 Answers4

24

Polling was added in 3.0.0.

You can activate it with the poll option.

var w = watchify(b, {
  poll: true
});

From docs: opts.poll enables polling to monitor for changes. If set to true, then a polling interval of 100ms is used. If set to a number, then that amount of milliseconds will be the polling interval. For more info see Chokidar's documentation on "usePolling" and "interval". This option is useful if you're watching an NFS volume.

Matt Rose
  • 515
  • 3
  • 8
  • This should be marked as the valid answer. While running gulp in a VM environment watchify doesn't work without polling. – Krasimir Jan 19 '16 at 13:47
17

This is because watchify relies on inotify to detect file changes which works great as long as they are initiated from inside your virtual machine (e.g. using touch on these files). However, it won't pick up changes performed outside because of a limitation with VirtualBox that doesn't trigger appropriate events in the guest system when a file is changed in the host system. Apparently VMware suffers from the same problem.

There are currently some discussions to fall back to polling for network mounts in watchify and chokidar (which watchify actually uses to watch files) to alleviate this particular problem:

Stéphane
  • 3,884
  • 1
  • 30
  • 27
10

I was having the same issue, and I discovered that it's not that the watchify update event never fires, it's that it doesn't output any logging information by default.

If you change your update binding to this, I think you'll discover that it's actually firing:

// this is never fired!
bundler.on('update', function () {
    console.log('update event');
    bundle();
});

That's why in gulp starter they built a custom logger for bundling.


Update: Danny Moerkeke (OP) wrote: "I already tried this to verify the handler is fired and it's not. BUT your answer sent me in the right direction cause when I edit the file with vi directly in the VM it works! The workspace is mounted to a shared folder inside vagrant and I run gulp inside this VM as well. When i edit the file in my editor on the host the update event is not fired so apparently something here is not working well with vagrant shared folders. When I run gulp on the host everything works fine. The idea was to keep everything inside the VM but actually this is fine (and faster!)"

Nate
  • 4,718
  • 2
  • 25
  • 26
  • 3
    Thanks for taking the time Nate. I already tried this to verify the handler is fired and it's not. BUT your answer sent me in the right direction cause when I edit the file with vi directly in the VM it works! The workspace is mounted to a shared folder inside vagrant and I run gulp inside this VM as well. When i edit the file in my editor on the host the update event is not fired so apparently something here is not working well with vagrant shared folders. When I run gulp on the host everything works fine. The idea was to keep everything inside the VM but actually this is fine (and faster!) – Danny Moerkerke Jan 06 '15 at 21:33
  • I'm sorry my answer wasn't correct, but I'm glad that I was able to play however small a part in nudging you toward your actual problem. – Nate Jan 06 '15 at 22:47
  • wasted a day on this...Same issue the update never fired from the gulp that was running in the host on my vagrant machine. ran the same gulp from my host machine and it worked ! thanks... – Shankar ARUL Jan 10 '15 at 15:06
5

Setting the synced folder system to RSync in the Vagrantfile solved my problem.

With this feature enabled, when you change files in your editor on the host, it will be copied on the fly via RSync on the guest and trigger the watcher events accordingly.

To do so, just add the following configuration to your file:

Vagrant.configure("2") do |config|
  config.vm.synced_folder ".", "/vagrant", type: "rsync",
end

In your terminal, start a vagrant session with the following command :

vagrant up && vagrant rsync-auto

http://docs.vagrantup.com/v2/synced-folders/rsync.html

griable
  • 892
  • 9
  • 9