nrwl / nx

Smart Monorepos · Fast CI
https://nx.dev
MIT License
23.49k stars 2.34k forks source link

React HMR #28189

Closed unknownconstant closed 1 week ago

unknownconstant commented 3 weeks ago

Current Behavior

Following on from #22658 which I didn't provide a repro from, I've come back to re-try inference as there's been more time for things to mature and become more stable.

I got the same issue: new project but no HMR using webpack in a generated react project. I was able to fix it by adding 'hot: true' to the webpack devserver config. This isn't intuitive as webpack's devserver appears to use HMR anyway, I'm left unsure why adding this explicit flag changed anything.

Expected Behavior

HMR should work out of the box, OR, some obvious message which explains why its not working, or that the hot: true line needs to be manually added etc.

The fact it was a one-line fix is bittersweet because it's taken a significant amount of time to track down. Because it's so simple to fix I'm unsure if this is me missing something I should have known, or if this is a gap in nx's testing. HMR appears to work from the terminal.

GitHub Repo

No response

Steps to Reproduce

Create new project using generator

Call npx create-nx-workspace from parent dir:

Where? nx-repro
Stack? none
Type? Integrated repo
CI? later
Remote caching? Absolutely not

Demo

Use nx serve nx-repro & open in browser

When making any changes (even non-code changes like adding a comment or line break), observe the browser console reports error similar to Aborted because 103 is not accepted and reloads the page. Terminal console:

Entrypoint main [big] 1.36 MiB (1.7 MiB) = runtime.js 47.1 KiB runtime.06a0bd1a0396bf8c.hot-update.js 343 bytes vendor.js 1.31 MiB main.js 2.36 KiB main.06a0bd1a0396bf8c.hot-update.js 2 KiB 5 auxiliary assets
Entrypoint styles [big] 244 KiB (398 KiB) = runtime.js 47.1 KiB runtime.06a0bd1a0396bf8c.hot-update.js 343 bytes styles.css 119 bytes styles.js 197 KiB 4 auxiliary assets
chunk (runtime: runtime) main.js, main.06a0bd1a0396bf8c.hot-update.js (main) 1.56 KiB [initial] [rendered]
chunk (runtime: runtime) runtime.js, runtime.06a0bd1a0396bf8c.hot-update.js (runtime) 31.6 KiB [entry] [rendered]
chunk (runtime: runtime) styles.css, styles.js (styles) 190 KiB (javascript) 80 bytes (css/mini-extract) [initial]
chunk (runtime: runtime) vendor.js (vendor) (id hint: vendor) 1.3 MiB [initial] split chunk (cache group: vendor) (name: vendor)
webpack compiled successfully (2d96a1f67e36e39e)
No errors found.

Fix

add hot: true, to webpack.config.js in devServer:

module.exports = {
...
  devServer: {
    port: 4200,
    historyApiFallback: {
      index: '/index.html',
      disableDotRule: true,
      htmlAcceptHeaders: ['text/html', 'application/xhtml+xml'],
    },
    hot: true,
  },
...

Observe that HMR updates are applied

Nx Report

Node           : 22.4.0
OS             : darwin-x64
Native Target  : x86_64-macos
yarn           : 1.22.19

nx (global)        : 17.0.2
nx                 : 19.8.2
@nx/js             : 19.8.2
@nx/jest           : 19.8.2
@nx/linter         : 19.8.2
@nx/eslint         : 19.8.2
@nx/workspace      : 19.8.2
@nx/devkit         : 19.8.2
@nx/eslint-plugin  : 19.8.2
@nx/react          : 19.8.2
@nrwl/tao          : 19.8.2
@nx/web            : 19.8.2
@nx/webpack        : 19.8.2
typescript         : 5.5.4
---------------------------------------
Registered Plugins:
@nx/webpack/plugin
@nx/eslint/plugin
@nx/jest/plugin

Failure Logs

No response

Package Manager Version

No response

Operating System

Additional Information

No response

unknownconstant commented 3 weeks ago

repro repo: https://github.com/unknownconstant/nx_28189 branch with fix https://github.com/unknownconstant/nx_28189/tree/fixed

I appreciate the scale of nx means keeping everything working perfectly is difficult and I've noticed it's definitely got more stable over the years. When it works it's great.

I'm relieved to have found a solution but unnerved that I don't know why it didn't work initially, and don't know why the additional explicit config helped.

ndcunningham commented 1 week ago

I cloned your repo, https://github.com/unknownconstant/nx_28189 specifically main without making any changes and HMR is enabled.

Can you check your browser console?

Image

unknownconstant commented 1 week ago

@ndcunningham thanks for taking the time to review this.

Yes, I see the same thing in the console, HMR is seemingly enabled. When you then make a code (well, any) change and the HMR triggers, the update fails to render in the browser and a full page refresh is triggered.

So the point is in main it appears that HMR is enabled, and everything looks good up until you actually make a change and it cannot apply the update.

I don't know what the difference is, but I've been able to replicate this across Mac & windows, different browsers, with new nx repos & old nx repos, and the repro I linked here.