Understanding Webpack HMR

November 5th, 2015

Hot Module Replacement, or HMR, is essential for the fast and efficient client-side Javascript developer. I know this, and yet recently found myself not using it in my recent projects. Why?

I didn't understand how HMR works. Sometimes my projects didn't exactly match the provided examples or starter projects - and then I became lost.

If you've never heard of hot module replacement before, start by reading about why you should use it.

Read on to get a deep understanding of what HMR is and how it works so you can use it in all your projects.

What is HMR?

Hot Module Replacement is a Webpack feature that updates your Javascript without a browser reload. The 'module' in hot module replacement just refers to each of your Javascript source code files.

To make these updates happen, Webpack installs the HMR Runtime into your output bundle. This is extra code that Webpack adds to your bundle so that it can run in the browser and receive module updates.

Another key component is the HMR Server. The HMR Server notifies the HMR Runtime when an update has occurred and it provides those updates in .json format.

See how the HMR Runtime and the HMR Server fit into the big picture in the next section.

How does HMR work?

I'm so glad you asked! I happen to have a spiffy diagram to show you.

webpack overview diagram

Terms

Let's start by going over all the pieces introduced in the diagram, then we can talk about how they work together.

  • Webpack Compiler: The core of Webpack is the compiler. This does the heavy lifting of turning your JS into a bundle.
  • HMR Server: Provides the hot module updates to the HMR Runtime.
  • Bundle Server: Provides the bundle.js to the browser.
  • bundle.js: This is javascript file that gets added as a <script> tag in the browser. It's usually served by the Bundle Server at something like http://localhost:8080/bundle.js.
  • HMR Runtime: This is the code that gets injected into your bundle.js. It communicates with the HMR server and updates the modules in your code.

Launch Flow

When you first run the HMR server, (using webpack-dev-server or webpack-hot-middleware), an initial bundle needs to be created. This same process happens regardless of whether or not you are using HMR.

  1. Webpack Compiler compiles your JS code.
  2. Bundle Server serves your bundle.js to the browser.

Glance back up at the diagram to see where A and B fit into the bigger picture.

Update Flow

When you make a change in your text editor, a sequence of events needs to take place to deliver an updated module to the browser.

  1. You make a change to one of your text files.
  2. File System picks up the change and informs Webpack.
  3. Webpack Compiler rebuilds one or more modules and informs the HMR Server that an update has been made.
  4. HMR Server uses websockets to inform the HMR Runtime that it needs an update. HMR Runtime requests those updates over HTTP .
  5. HMR Runtime replaces the modules in the update - OR - if it determines those modules can't be updated, triggers a full page refresh.

Here's the diagram again so you can visualize the process.

webpack overview diagram

More on the HMR Runtime

The HMR Runtime is a pretty big piece of this puzzle. It swaps out your old code for new code.

The most important thing to remember about the HMR Runtime is that it can't automatically undo any side effects of your old code. That's why you have to use module.hot.dispose() to undo any side effects. Read more about the module.hot API in the webpack HMR docs.

So What Now?

Use this knowledge of how HMR works and apply it to your projects! Now you understand that HMR is really a server and a runtime. When configuring your Webpack projects you need to make sure that both get set up.

If you need help getting set up - follow my webpack HMR tutorial. I'll tell you about the 3 ways to set up HMR, and point you towards the approach that fits your situation.

⇣ And if you liked the article, don't forget to sign up for updates! ⇣