DEV Community

Rex
Rex

Posted on • Edited on

4 2

Enable Hot Module Replacement(HMR) in Nrwl/Nx React Project

HMR offer many benefits. Here is a quote from the official webpack website:

Hot Module Replacement (HMR) exchanges, adds, or removes modules while an application is running, without a full reload. This can significantly speed up development in a few ways:

Retain application state which is lost during a full reload.

Save valuable development time by only updating what's changed.

Instantly update the browser when modifications are made to CSS/JS in the source code, which is almost comparable to changing styles directly in the browser's dev tools.

Nrwl/Nx for React doesn't come with HMR by default. There is a long-standing issue for this and I waited for a workable solution for a long time, and finally, we got it. So the solution is in the issue and this blog is to save everybody's time trying to piece together a workable solution.

  1. Add below to package.json in the devDependencies section and install.

    "webpack": "^4.46.0", (5.x doesn't work)
    "@pmmmwh/react-refresh-webpack-plugin": "^0.4.3",
    "react-refresh": "^0.10.0",
    
  2. Create a new file webpack.config.js or another name, to host your custom webpack configuration, I put it in my app folder

    const getWebpackConfig = require('@nrwl/react/plugins/webpack');
    const ReactRefreshPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
    function getCustomWebpackConfig(webpackConfig) {
    const config = getWebpackConfig(webpackConfig);
    const isProduction = webpackConfig.mode === 'production';
    if (!isProduction) {
    webpackConfig.devServer = {
    ...webpackConfig.devServer,
    hot: true,
    };
    config.plugins.push(new ReactRefreshPlugin());
    }
    return config;
    }
    module.exports = getCustomWebpackConfig;
  3. Edit workspace.json to configure Nx to use the above custom webpack configuration.
    Find projects/[your app]/targets/build/options section, add this line to the end of the options section: "webpackConfig": "[path to]/webpack.config.js. ([your app] is your app's name.)
    Mine looks like this:

    ...
    "projects": {
    "app": {
    "root": "apps/app",
    "sourceRoot": "apps/app/src",
    "projectType": "application",
    "targets": {
    "build": {
    "executor": "@nrwl/web:build",
    "outputs": ["{options.outputPath}"],
    "options": {
    "outputPath": "dist/apps/app",
    ...
    "webpackConfig": "apps/app/webpack.config.js"
    },
    "configurations": {
    ...
    view raw workspace.json hosted with ❤ by GitHub
  4. update file .babelrc to add react-refresh/babel plugin. Mine looks like this:

    {
    "presets": [
    [
    "@nrwl/react/babel",
    {
    "runtime": "automatic"
    }
    ]
    ],
    "env": {
    "development": {
    "plugins": ["@emotion/babel-plugin", "react-refresh/babel"]
    },
    "production": {
    "plugins": ["@emotion/babel-plugin"]
    }
    }
    }
    view raw .babelrc hosted with ❤ by GitHub

After above, you would see something like this in your console:

[WDS] App updated. Recompiling...
reloadApp.js:19 [WDS] App hot update...
log.js:24 [HMR] Checking for updates on the server...
log.js:24 [HMR] Updated modules:
log.js:24 [HMR] - ../../../libs/[path of changed file here]
log.js:24 [HMR] App is up to date.

What I love about it is that I know exactly when the app is up to date, no more guessing. It is so much better than the silent console of Create React App. I had to go to the Network tab to see if the app is updated; I ended up refreshing the browser most of the time to be sure the update has taken place.

Update: 25/05/2021

After two weeks of using the shining new HMR above, I am back to report that I am very happy with the solution.

I repeat, I love that NX tells me when exactly the app is hot loaded and up to date, making it better than react-react-app, which is silence on hot reload in the console(last time I tried, two months back).

A few things to note:

  1. stick to one export per file to make HMR work consistently
  2. when adding/removing hooks, HMR fails and an error message appears. make sense, nothing to complain
  3. react-refresh catches all console error messages and make them full screen, at first it is kinda annoying because of some vendor error, then I realised that it is there for a good reason, it forces me to fix the errors even if it is from third-party libraries, from which I always learn something new.

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more

Top comments (3)

Collapse
 
dannysofftie profile image
Danny Sofftie

This saved me 2 days of research

Collapse
 
starkhk profile image
Hemant Kaushik • Edited

Will this work in Nexj v13 too?

Collapse
 
rexebin profile image
Rex

Not sure, the latest nx now come with HMR enabled by default. Vite has HMR too. Toolings are getting better😄

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay