When I use React Fast Refresh with Webpack 5, the whole page is refreshed instead of just the component that changed.
EDIT the issue was caused by Webpack configuration, a proper configuration to fix the problem is posted as an answer below.
I figured out the issue after looking into the official examples (thanks to @Keith for pointing me towards them).
The main issue was my index.html
included a link to the bundle.js
that wasn't needed. My Webpack configuration also included extra unnecessary configurations like devMiddleware
& static
properties.
Here's my folder structure:
.
├── README.md
├── babel.config.js
├── package-lock.json
├── package.json
├── public
│ └── index.html
├── src
│ ├── Hello.jsx
│ └── index.jsx
└── webpack.config.js
I'm providing my index.html
, webpack.config.js
, and bable.config.js
here for future references:
const path = require("path");
const ReactRefreshPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const isDevelopment = process.env.NODE_ENV !== "production";
module.exports = {
mode: isDevelopment ? "development" : "production",
devServer: {
hot: true,
client: {
logging: "error",
overlay: true,
},
},
entry: ["./src/index.jsx"],
module: {
rules: [
{
test: /\.jsx?$/,
include: path.join(__dirname, "src"),
use: "babel-loader",
},
],
},
plugins: [
isDevelopment && new ReactRefreshPlugin(),
new HtmlWebpackPlugin({
filename: "./index.html",
template: "./public/index.html",
}),
].filter(Boolean),
resolve: {
extensions: [".js", ".jsx"],
},
};
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Webpack 5 And React Fast Refresh</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
module.exports = (api) => {
// This caches the Babel config
api.cache.using(() => process.env.NODE_ENV);
return {
presets: [
"@babel/preset-env",
// Enable development transform of React with new automatic runtime
[
"@babel/preset-react",
{ development: !api.env("production"), runtime: "automatic" },
],
],
// Applies the react-refresh Babel plugin on non-production modes only
...(!api.env("production") && { plugins: ["react-refresh/babel"] }),
};
};