https://github.com/James2516/hot-reload
I'm trying to add hot loader to an existing webpack project.
It detected file changes but did not reload the component.
To reproduce:
yarn && yarn start
src/App.js
contentThe examples are taken from https://gaearon.github.io/react-hot-loader/getstarted/#step-2-of-3-using-hmr-to-replace-the-root-component, though it seems as though you already followed this guide.
The first problem is that [HMR] Waiting for update signal from WDS...
is printed to the console twice, and any attempted recompiles also occur twice. This is caused by your entry
in ./config/webpack/Dev.js
being:
entry: [
'webpack-dev-server/client?http://localhost:4545/',
'webpack/hot/only-dev-server',
'react-hot-loader/patch',
'./client.js',
]
The first few steps of the guide have the entry point as:
[
'webpack-dev-server/client?http://0.0.0.0:3000', // WebpackDevServer host and port
'webpack/hot/only-dev-server', // 'only' prevents reload on syntax errors
'./scripts/index' // Your app's entry point
]
Step 3a under Step 3 (of 3): Adding React Hot Loader to preserve component state instructs you to modify the entry
of webpack.config.js
to look like:
[
'react-hot-loader/patch', // RHL patch
'./scripts/index' // Your app's entry point
]
react-hot-loader
handles what these two entries were previously doing, so they can be replaced with 'react-hot-loader/patch'
.
So your new entry point should be:
[
'react-hot-loader/patch',
'./client.js'
]
Next, Step 3b in the same section has a code snippet that looks like:
if (module.hot) {
module.hot.accept('./containers/rootContainer.js', () => {
const NextRootContainer = require('./containers/rootContainer').default;
render(NextRootContainer);
});
}
Changing your module.hot
block to:
if (module.hot) {
module.hot.accept('./App', () => {
const newApp = require('./App').default;
render(newApp);
}
}
Correctly reloads the component, so it doesn't make sense that following Step 3c breaks HMR.
c. Webpack 2 has built-in support for ES2015 modules, and you won’t need to re-require your app root in module.hot.accept. The example above becomes:
if (module.hot) { module.hot.accept('./containers/rootContainer', () => { render(RootContainer) }); }
Note: To make this work, you’ll need to opt out of Babel transpiling ES2015 modules by changing the Babel ES2015 preset to be
"presets": [["es2015", { "modules": false }]]
Which you did correctly in .babelrc
. The only problem is that in ./config/webpack/Base.js
you have:
loader: 'babel-loader',
query: {
presets: ['es2015', 'react', 'stage-2']
}
This causes babel-loader
to use these presets instead of the ones defined in .babelrc
. Removing query
in this rule and changing presets
in .babelrc
to:
"presets": [["es2015", { "modules": false }], "react", "stage-2"
Correctly enables HMR with your module.hot
block as:
if (module.hot) {
module.hot.accept('./App', () => { render(App); });
}