How to live reload webpack-dev-server when saving external files

8 months ago
#javascript#webpack

We're going to write a small webpack plugin for people who develop with webpack's dev-server without HMR. When saving files in your bundle, webpack will live reload the browser. But what if you want your browser to refresh when saving files outside your bundle? For example some template files, or configuration files.

What? Write a webpack plugin?

If you just got scared when reading "write a small webpack plugin", don't be! Although I have this snippet in my webpack's config file for some time now, I recently got reminded by Sean Larkin's awesome presentation that we're not doing rocket science here.

If the only thing you take away from this post is that writing a webpack plugin is not that hard, then you just made my day. And seriously, go watch his presentation "Eveything's a plugin" right now!

But back to our problem

We want our browser to refresh when we save some file that's not in the bundle's scope. What we can do is add extra context dependancies to webpack's compilation object. The following script (aka webpack plugin) is a way to make that happen.

/*
 * Custom plugin to trigger a compile when 
 * saving files outside the bundle
 */
const WatchExternalFilesPlugin = () => {
  WatchExternalFilesPlugin.prototype.apply = (compiler) => {
    compiler.plugin('after-compile', (compilation, callback) => {
      ['./templates', './config', './modules'].forEach(path => compilation.contextDependencies.add(path));
      callback();
    });
  };
};

/*
 * Add it to your Webpack config
 */
yourWebpackConfig.plugins.push(new WatchExternalFilesPlugin());

We're hooking into the compiler's after-compile event, which returns the compilation object. We can then add 'extra things to watch' to it by using the contextDependancies.add() method.

What it does is tell webpack to watch extra files next to the ones that it will watch by default based on your webpack config. The method expects a path, and whatever we will pass in it will trigger a compile (and a browser refresh when DevServer is running) when saving.

This looks technical, can't I just use LiveReload.js?

Of course, LiveReload is a great tool. But refreshing your page when your code changes is something that's already built-in in webpack. This scripts just makes use of the already built-in features of webpack. 

Secondly if you use this script, you can really watch any files. Not just the the templates of your site. When I'm developing a site with Craft CMS, I watch my config folder, modules & templates folder. 

I hope you see the benefit of implementing a live reload feature into your webpack config this way. And that it will speed up your development time a bit.