Hot reloading with create-react-app without ejecting šŸ”„ āļø

ā€¦and without react-app-rewired.

Brian Han
3 min readFeb 27, 2018
Very awesome but way-too-serious photo for this article because I guess the theme is ā€œhotā€? So, like ā€œfireā€? Aziz Acharki on Unsplash

With a few lines of code, you can setup a new create-react-app project with hot-module-replacement (HMR).

Spin up a new react app withnpx create-react-app your-new-app and update the index.js file and voila (see the gist below).

Gist from Charlie Gleasonā€™s post on ā€œHot Reloading + create-react-app"

But what if I start adding other react things?

  • react-router-dom
  • redux
  • react-redux

Suddenly, HMR doesnā€™t work when I wrap my App with Provider and BrowserRouter.

I googled around for clues and found my aha moment in the create-react-app github issues:

I tweaked my code accordingly and now my app works with HMR functioning correctly. See with the gists below.

Thatā€™s it.

You can stop reading now.

The rest of this article is a bunch of crazy notes because I feel terrible about not knowing how any of this stuff works. The ā€œwebpack-layerā€ is magic to me and Iā€™d like to understand it better. Itā€™s the off-chance that youā€™ll continue reading that motivates me to write anything at all. SO even though these are notes for myselfā€¦thanks for reading and hope you get something out of this.

Thereā€™s a ā€œwebpack-shapedā€ hole in my brain

Oh, youā€™re still here? Alright..wellā€¦

Iā€™m going to allow my webpack-noobness to show a little: I donā€™t know webpack well enough to work with it directly. I do my best to avoid ejecting my projects that use create-react-app. Apologies if this offends anyone but šŸ¤·ā€ā™‚ļø

Even though I have HMR playing nicely with everything else, now I get to use the code I have to understand whatā€™s going on under-the-hood.

Attempting to understand

This module.hot code seems to be the thing ā€” I think itā€™s a webpack thing.
Iā€™m going to go read these docs and these docs. Iā€™ll update this later with some better written thoughts. Hereā€™s a donut šŸ©, enjoy!

API

The API for module.hot looks like itā€™s short and sweet.

if (module.hot) {
module.hot.accept('./library.js', function() {
// Do something with the updated library module...
})
}
  • Check if there are any spicy modules
  • accept them spicy mods
  • do something in the callback with that module

This makes sense so farā€¦App should be accepted, and we get the updated App component and render it with ReactDOM.render in the callback.

if (module.hot) {  
module.hot.accept('./App', () => {
const NextApp = require('./App').default;
// render with new App here
});
}

But a few things are still weird to me:

  1. Why is it okay to give module.hot.accept a string like, './App'?
    My guess here is that something is happening under the hood thatā€™s resolving the string './App' to the actual App component. Or itā€™s some reference?
  2. What the heck is require('./App').default?
    This exchange on stackoverflow is the closest thing I can find to an answer, so Iā€™ll need to dig into this a little more.

Other cool stuff

Ejecting create-react-app reveals the webpack config files.

One thing to note is that thereā€™s a custom dev client being used:

{
entry: [
require.resolve('react-dev-utils/webpackHotDevClient'),
],
}

Thereā€™s also a comment that explains that this basically replaces this code but with added features for better dev experience, like error display:

require.resolve(ā€˜webpack-dev-server/clientā€™) + ā€˜?/ā€™, require.resolve(ā€˜webpack/hot/dev-serverā€™),

Links

--

--

Brian Han

UX Developer @ Indeed // Previously: Accenture, IBM, Carbon Design System