docs/oss/building-features/hmr-and-hot-reloading-with-the-webpack-dev-server.md
The webpack-dev-server provides:
react-hot-loader has been deprecated in
favor of fast-refresh.
For use with Webpack, see Client Side rendering and HMR using react-refresh-webpack-plugin section below or visit react-refresh-webpack-plugin for additional details.If you are not using server-side rendering (not using prerender: true),
then you can follow all the regular docs for using the bin/shakapacker-dev-server
during development.
If you are using server-side rendering, then you have a couple of options. The recommended technique is to have a different Webpack configuration for server rendering.
If you do use the webpack-dev-server for prerendering, be sure to set the
config/initializers/react_on_rails.rb setting of
config.same_bundle_for_client_and_server = true
dev_server.hmr maps to devServer.hot.
This must be false if you're using the webpack-dev-server for client and server bundles.
If hmr is true when using the same bundle for client and server, you will see: ReferenceError: window is not defined
To enable the HMR functionality, you have to use ./bin/shakapacker-dev-server
In config/shakapacker.yml, set the hmr property under dev_server to true.
dev_server:
https: false
host: localhost
port: 3035
public: localhost:3035
hmr: true
Add react-refresh packages:
yarn add -D @pmmmwh/react-refresh-webpack-plugin react-refresh
# or: npm install -D @pmmmwh/react-refresh-webpack-plugin react-refresh
# or: pnpm add -D @pmmmwh/react-refresh-webpack-plugin react-refresh
HMR is for use with the webpack-dev-server, so we only add this for the webpack-dev-server.
const { devServer } = require('shakapacker');
const isWebpackDevServer = process.env.WEBPACK_DEV_SERVER;
// plugins
if (isWebpackDevServer) {
environment.plugins.append(
'ReactRefreshWebpackPlugin',
new ReactRefreshWebpackPlugin({
overlay: {
sockPort: devServer.port,
},
}),
);
}
We added overlay.sockPort option in ReactRefreshWebpackPlugin to match the webpack-dev-server port specified in config/shakapacker.yml. This makes SockJS works properly and fixes this error in browser console: GET http://localhost:[port]/sockjs-node/info?t=[xxxxxxxxxx] 404 (Not Found). When using ReactRefreshWebpackPlugin with v0.6.0 and newer, overlay.sockPort is no longer supported and should be omitted from the configurations.
Add the react-refresh plugin in babel.config.js
module.exports = function (api) {
return {
plugins: [process.env.WEBPACK_DEV_SERVER && 'react-refresh/babel'].filter(Boolean),
};
};
That's it :).
Now the browser should reflect changes in .js and .css files without reloading.
If for some reason the plugin doesn't work, you can revert the changes and leave only dev_server.hmr set to true, affecting only CSS files.
These plugins are working and tested with
configuration.