Reputation: 16479
I got my webpack Hot Module Replacement working. I was told that once it is working, I would no longer have to do a full refresh for my code. This is not the case! I still require a refresh when I make changes to my code! (App.js
).
How can I properly enable webpack HMR?
Link to the project on github
This is my entry point
import './styles/index.css';
import App from './components/App';
import React from 'react';
import { render } from 'react-dom';
const rootDOMNode = document.getElementById('app');
function renderRoot() {
render(<App/>, rootDOMNode);
}
renderRoot();
if (module.hot) {
module.hot.accept('./components/App', () => {
console.log('Accepting the updated module');
renderRoot();
});
}
webpack.config.js:
const webpack = require("webpack");
const path = require("path");
const CleanWebpackPlugin = require( "clean-webpack-plugin");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: [
"./app/index"
],
devtool: "inline-source-map",
output: {
path: path.resolve(__dirname, "dist"), // Note: Physical files are only output by the production build task `npm run build`.
publicPath: "/",
filename: "bundle.js"
},
devServer: {
contentBase: path.resolve(__dirname, "dist"),
hot: true,
port: 3000,
open: true,
compress: true
},
plugins: [
new ExtractTextPlugin({
disable: false,
filename: "css/style.css",
allChunks: true
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
],
module: {
rules: [
{ test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: ['env', 'react']
}
} },
// { test: /(\.css)$/, use: ["style-loader", "css-loader"] },
{ test: /(\.css)$/, use: ExtractTextPlugin.extract(["css-loader"]) },
{ test: /\.(png|svg|jpg|gif)$/, use: ["file-loader"] },
// for fonts
{ test: /\.(woff|woff2|eot|ttf|otf)$/, use: ["file-loader"] }
]
}
};
Upvotes: 1
Views: 121
Reputation: 2896
The reason it is not working is because you have to re-require your app
once you get the hot update, otherwise you are just re-rendering your original app.
the following code should work:
import './styles/index.css';
//import App from './components/App';
import React from 'react';
import { render } from 'react-dom';
const rootDOMNode = document.getElementById('app');
let App;
function renderRoot() {
App = require('./components/App').default; // we have to re-require this every time it changes otherwise we are rendering the same old app.
render(<App/>, rootDOMNode);
}
renderRoot();
if (module.hot) {
module.hot.accept('./components/App', () => {
console.log('Accepting the updated module');
renderRoot();
});
}
Upvotes: 1
Reputation: 555
I use hot reloading with webpack-dev-server by adding a script in package.json.
webpack-dev-server --output-public-path=/dist/ --inline --hot
Upvotes: 1