Webpack Watch in Vagrant/Docker

August 27th, 2015

So you just got Webpack all set up, and you're using Vagrant or Docker. Then you run webpack --watch. But when you make changes in your favorite text editor, Webpack doesn't even notice! It does nothing! Why?

First let's discuss how this normally works on Linux:

  • You run webpack --watch, which subscribes to file changes using inotify.
  • You make changes in your text editor.
  • inotify picks up the changes and reports them to Webpack.
  • Webpack does a rebuild, yay!

Now let's discuss where this breaks down in your VM:

  • You run webpack --watch inside your VM.
  • You make changes in your text editor, on the host machine (your laptop).
  • The file changes on disk, on the host.
  • Your VM software (maybe VirtualBox) syncs your changes to your VM using NFS.
  • ... ... ... silence. crickets. nothing else happens.

But why not? Why doesn't VirtualBox use inotify to send the changes over?

Let's go to wikipedia:

Notification via inotify requires the kernel to be aware of all relevant filesystem events, which is not always possible for networked filesystems such as NFS ...

Okay, so it's hard. But surely VirtualBox will add this feature eventually right?

Nope. Issue filed, and set to wontfix.

Okay but what about VMWare? You could buy that, or maybe you're already using it.

That won't work either. According to the creator of Vagrant, inotify doesn't work with VMWare shared folders, either.

So what do we do??? Do we abandon virtualization altogether??? No.

The solution

The answer is polling. This just means that Webpack will check every few hundred milliseconds to see if your files have been updated. It won't be QUITE as snappy as you'd hoped, but it will work.

Here's the relevant portion of your Webpack config:

watchOptions: {
  poll: true;
}

For more details, see the Webpack docs on watchOptions.poll.

I've been talking specifically about Webpack, but polling is the solution whenever you want a VM to notice changes made outside that VM.

Bonus: Karma Config

Using Karma with Webpack? Add this to your karma.conf.js:

webpackMiddleware: {
  watchOptions: {
    poll: true;
  }
}

Double Bonus: CPU Spike Workaround

If polling causes your CPU to spike, then set the polling frequency lower. So instead of poll: true, use poll: 300 (for 300ms) or poll: 500 (for 500ms). Try progressively higher numbers until your CPU usage problem goes away.