Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HMR for @nrwl/react #1881

Closed
Tracked by #1
marazz1 opened this issue Sep 24, 2019 · 40 comments
Closed
Tracked by #1

HMR for @nrwl/react #1881

marazz1 opened this issue Sep 24, 2019 · 40 comments
Labels
outdated scope: react Issues related to React support for Nx type: feature

Comments

@marazz1
Copy link

marazz1 commented Sep 24, 2019

How to enable HMR for @nrwl/react. Is it possible to achieve it without custom webpack.config.json? (Like in Angular)

There should be something in docs for HMR.

In workspace.json "hmr": true

"serve": {
          "builder": "@nrwl/web:dev-server",
          "options": {
            "hmr": true,
            "buildTarget": "testapp:build"
          },
          "configurations": {
            "production": {
              "buildTarget": "testapp:build:production"
            }
          }

Expected Behavior

module.hot should not be undefined

Current Behavior

HMR doesn´t work.

Context

    "@nrwl/cypress": "8.5.1",
    "@nrwl/eslint-plugin-nx": "8.5.1",
    "@nrwl/jest": "8.5.1",
    "@nrwl/react": "8.5.1",
    "@nrwl/web": "8.5.1",
    "@nrwl/workspace": "8.5.1",
@FrozenPandaz FrozenPandaz added the scope: react Issues related to React support for Nx label Dec 6, 2019
@github-actions github-actions bot added the stale label May 29, 2020
@nrwl nrwl deleted a comment from github-actions bot May 29, 2020
@FrozenPandaz
Copy link
Collaborator

Hi, sorry about this.

This was mislabeled as stale. We are testing ways to mark not reproducible issues as stale so that we can focus on actionable items but our initial experiment was too broad and unintentionally labeled this issue as stale.

@jaysoo jaysoo removed their assignment Jun 8, 2020
@BigAB
Copy link
Contributor

BigAB commented Jun 15, 2020

So, as...

We have decided to wait until there is a webpack solution for React Fast Refresh solution for Webpack and we'll implement HMR for our React projects with that when it arrives

@Hotell
Copy link
Contributor

Hotell commented Jun 16, 2020

Makes sense! Thx

@cafesanu
Copy link

cafesanu commented Oct 3, 2020

Hi @BigAB! Seems like webpack is now supported 😄 . Here is a copy-paste of the current state in https://github.com/gaearon/react-hot-loader

Thanks!

@R4VANG3R
Copy link

Create react app 4.0 now also released with Fast Refresh using this plugin: pmmmwh/react-refresh-webpack-plugin#1

@pitops
Copy link

pitops commented Oct 28, 2020

any update on this?

@cafesanu
Copy link

@BigAB Wondering if there is any news here? This would be a great improvement for the nrwl react community 🙂

Thanks!

@nemonemi
Copy link

Just a reminder, would be nice to have an answer here to know of the progress.

@capJavert
Copy link

@nemanjamilosavljevic-newtron actually we managed to integrate https://github.com/pmmmwh/react-refresh-webpack-plugin into our nx setup (we have few react based application). It is working great so far.

We followed https://github.com/pmmmwh/react-refresh-webpack-plugin/tree/main/examples/webpack-dev-server example. Only thing that was needed is to upgrade webpack to at least 4.43.0 (this is slightly higher that current nx version). But again no issues in the last month of usage.

So maybe there is no need to wait for this feature to land into NX, you can jump in right now.

@nemonemi
Copy link

@capJavert Thanks for responding so quickly :)

I'm new to NX so I hope you could help me with the following:
Where can I find documentation on updating and configuring webpack (just update the nx cli?). https://nx.dev/react/guides/cli returns 404

@capJavert
Copy link

Just adjust webpack dependency version in you package.json or add it through yarn add [email protected]

@nemonemi
Copy link

Thank you @capJavert
However, it would be nice to have this integrated.

@rexebin
Copy link

rexebin commented Feb 19, 2021

I have had a go to get HMR, but no luck. Stil compiles, but WDS only, no HMR. webpack.config.js is as below. I also added "react-refresh/babel" to .babelrc plugins list. No affect what so ever. I am lucky it still compiles, no idea of how babel/webpack works together.

const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const webpack = require('webpack');
const isDevelopment = process.env.NODE_ENV !== 'production';
module.exports = (config, context) => {
  return {
    ...config,
    mode: isDevelopment ? 'development' : 'production',
    module: {
      ...config.module,
      rules: [
        ...config.module.rules,
        // ... other rules
        {
          test: /\.([jt])sx?$/,
          exclude: /node_modules/,
          use: [
            {
              loader:
                '@nrwl/web/src/utils/web-babel-loader',
              options: {
                rootMode: 'upward',
                cwd: 'apps/myapp/src',
                isModern: true,
                envName: undefined,
                babelrc: true,
                cacheDirectory: true,
                cacheCompression: false,
                plugins: [
                  // ... other plugins
                  isDevelopment && require.resolve('react-refresh/babel'),
                ].filter(Boolean),
              },
            },
          ],
        },
      ],
    },
    plugins: [
      ...config.plugins,
      isDevelopment && new webpack.HotModuleReplacementPlugin(),
      isDevelopment && new ReactRefreshWebpackPlugin(),
    ].filter(Boolean),
  };
};

@capJavert
Copy link

capJavert commented Feb 20, 2021

@rexebin you are probably missing devServer.hot property for weback. Something like this will do:

// ...

webpackConfig.devServer = {
    ...webpackConfig.devServer,
    hot: true
}

// ...

More here: https://webpack.js.org/guides/hot-module-replacement/#enabling-hmr

@SDemonUA
Copy link

I got messages like: [HMR] App is up to date., but no actual rerender. Making me mad...

@SDemonUA
Copy link

I got messages like: [HMR] App is up to date., but no actual rerender. Making me mad...

Problem hides in React version - React Fast Refresh works only with 16.9+

@nemonemi
Copy link

@SDemonUA React Fast Refresh is not yet ready for official use. I have it in another project on version 17.0.1 and it works when other pages were changed, but not when the index.ts gets changed. Even then, I have to jump-start the tracking by refreshing the page and, then it works.
In the case of micro frontends, there's this issue facebook/create-react-app#10385

In case you want to have HMR, then you can easily disable the fast refresh to have it working.
facebook/create-react-app#10539

@github-actions
Copy link

This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs.
If we missed this issue please reply to keep it active.
Thanks for being a part of the Nx community! 🙏

@github-actions github-actions bot added the stale label Mar 29, 2021
@dcastil
Copy link

dcastil commented Mar 29, 2021

Not stale, I'm waiting for this! 😄

@github-actions github-actions bot removed the stale label Mar 29, 2021
@rexebin
Copy link

rexebin commented Apr 6, 2021

I tried react-react-app with fast refresh and found myself constantly refreshing manually and eventually turn off fast refresh all together.

It works ok most cases but requires manual refreshing in some cases. The thing is, this small chance of non-op is making me doubtful all the time. I do not want to waste time trying to figure out why something is not working as intended, then find out a manual refresh is all I needed. Some may not have this problem.

Now I am back to NX with all the goodies Nx has to offer, feeling at home, not missing HMR, not a tiny bit.

@jugglingcats
Copy link

@rexebin I agree that the nagging doubt about whether refresh has happened is a pain with fast refresh. I'm using Snowpack and it works really well most of the time. There is an issue that changing a file with a React context provider often makes the context null for child components and the page then fails with an error, but I can live with that. For me the huge advantage is being able to work on something like a modal without having it disappear all the time due to a full page reload

@rexebin
Copy link

rexebin commented Apr 6, 2021

@jugglingcats working on a modal is really a good use case for fast refresh.

I can tell when or if the fast refresh happens from the network tab.

Maybe it is just me tiered of manual refresh just in case. No doubt Fast refresh is a good to have feature!

@rexebin
Copy link

rexebin commented Apr 6, 2021

@jugglingcats are you using Snowpack with NX?

@jugglingcats
Copy link

@rexebin yes and no. I have an nx monorepo that has shared libs and an aws lambda project, and in it there is a webapp that I run with snowpack by carefully crafting the snowpack config... NX doesn't really know anything about it

@rexebin
Copy link

rexebin commented Apr 6, 2021

@jugglingcats searching about snowpack and nx, found your nx-snowpack repo. From one of the post from @vsavkin, it was hinted adding Snowpack to nx project is trivial.. interesting but at the same time feel uncertain.

@jugglingcats
Copy link

@rexebin we are getting a bit off topic from the original post perhaps, but I am interested in the difference (if any) between Snowpack refresh (using native modules/ESM) and NX (webpack) fast refresh.

I am using snowpack dev for everyday development and webpack optimize/bundle (driven by snowpack) for production build, and it works well for me. I haven't taken the time to compare with CRA or NX with fast refresh enabled as it's not easy to switch my large-ish project between the two.

@nemonemi
Copy link

nemonemi commented Apr 8, 2021

As mentioned by @jugglingcats, I think this thread has gotten slightly off-topic as well.
@vsavkin, @FrozenPandaz
It has been 2 years since this issue was first opened. It would be nice to see some progress here.
Could anyone from the maintainers please make an actionable item out of this?

@dustinlacewell
Copy link

Can anyone provide a minimal webpack override to enable fast refresh that works?

@capJavert
Copy link

capJavert commented Apr 17, 2021

Firstly you need to have minimal version of [email protected].

Minimal config would be (pretty much following install instructions at @pmmmwh/react-refresh-webpack-plugin:

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

Also you need to add react-refresh/babel plugin for production in your .babelrc.js or similar, example:

const commonPlugins = [/* your plugins here if you have any */]

module.exports = {
    presets: ['@nrwl/react/babel'],
    env: {
        development: {
            plugins: [...commonPlugins, 'react-refresh/babel']
        },
        production: {
            plugins: [...commonPlugins]
        }
    }
}

@nemonemi
Copy link

nemonemi commented May 6, 2021

Thanks for the code example, @capJavert!
However, for me the HMR works only for "upper" components, but not for the deeply nested components. On those, the full page reload is happening.

@vsavkin, @FrozenPandaz could you please address this request by at least providing proper documentation on how to handle this use case?

@xiongemi
Copy link
Collaborator

xiongemi commented May 8, 2021

@nemonemi i tried with the custom webpack on a simple app: https://github.com/xiongemi/nx-react-counter-custom-webpack and it seems to work fine for me for nested components. when I update a nested component, it does not trigger page reload. In the console, it says HMR is updating the components.

[HMR] Checking for updates on the server...
log.js:24 [HMR] Updated modules:
log.js:24 [HMR]  - ../../../libs/ui/src/lib/counter/counter.tsx
log.js:24 [HMR] App is up to date.

This is what my custom webpack looks like: https://github.com/xiongemi/nx-react-counter-custom-webpack/pull/1/files

Maybe disable the liveReload in your webpack file?

webpackConfig.devServer = {
      ...webpackConfig.devServer,
      liveReload: false,
      hot: true,
    };
    ```

@nemonemi
Copy link

Actually, I found what the problem was, and it was having multiple named exports in a component, which is a known behavior limit of the HMR library.

@rexebin
Copy link

rexebin commented May 13, 2021

I can confirm following the configuration showing at https://github.com/xiongemi/nx-react-counter-custom-webpack, I am able to get the HMR working in my Nx React Typescript project.

Nice console logs clearly showing the update progress like below:

[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.

I need to install three packages to get it working:

"webpack": "^4.46.0"(webpack 5 doesn't work),
"react-refresh": "^0.10.0",
"@pmmmwh/react-refresh-webpack-plugin": "^0.4.3"

@rexebin
Copy link

rexebin commented May 13, 2021

Actually, I found what the problem was, and it was having multiple named exports in a component, which is a known behavior limit of the HMR library.

Good to know, worth it to keep one export per file.

@nemonemi
Copy link

nemonemi commented May 13, 2021

Also, I found that no additional configuration of the .babelrc files is necessary.
This is my application's .babelrc file:

{
  "presets": ["@nrwl/react/babel"],
  "plugins": [
    [
      "styled-components",
      {
        "pure": true,
        "ssr": true
      }
    ]
  ]
}

@vsavkin
Please add this as a default for React projects!
It is hard to imagine anyone who doesn't want to have this improvement to the developer experience.

@rexebin
Copy link

rexebin commented May 25, 2021

After two weeks of using the shining new HMR above, I am back to report that I am very happy with the solution. Most important of all is 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. as mentioned above, I 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.

@nemonemi
Copy link

I'd like to add that I've tested the native HMR support by generating a new workspace with the latest version, and there it worked.

At the moment I am unable to migrate my project to the latest version of NX because of some issues with Yarn2, but it is worth investigating if HMR is supported natively by the NX with the latest versions.

p.s. I've checked the releases, and nowhere it is mentioned that they did anything in this direction, however, it works.

@xiongemi
Copy link
Collaborator

xiongemi commented Jun 9, 2021

the react fast fresh is added in or #5612, which is merged in https://github.com/nrwl/nx/releases/tag/12.3.5.
if you got an exiting nx repo, after you migrate a version >= 12.3.5 , you could turn it on by add "hmr": true in workspace.json -> projects -> -> targets -> serve -> options, like:

"serve": {
          "executor": "@nrwl/web:dev-server",
          "options": {
            "buildTarget": "react:build",
            "hmr": true,
          },

so when you run nx serve <your react app name>, you will have hmr enabled.

or you could just run serve command with hmr flag passed in like nx serve <your react app name> --hmr.

@FrozenPandaz
Copy link
Collaborator

Closing this issue as it's now implemented in #5612 🎉

@github-actions
Copy link

This issue has been closed for more than 30 days. If this issue is still occuring, please open a new issue with more recent context.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 23, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated scope: react Issues related to React support for Nx type: feature
Projects
None yet
Development

No branches or pull requests