Created by: pmmmwh
Fast Refresh requires the HMR runtime to support bail out behaviour (we do not do so within the core runtime as it has to be platform agnostic) - and currently webpackHotDevClient does not do so properly as it circumvents the logic for forced reloads completely when using Fast Refresh.
The changes done here ensures that:
- If Fast Refresh is not enabled, we would always bail out to a forced reload;
- If Fast Refresh is enabled and there are updated modules, it indicates the update has at least partially executed, and we can rely on Fast Refresh being resilient to errors and skip the forced reload;
- If Fast Refresh is enabled and there are none updated modules, check for the status of the hot update. If it is
abort
orfailed
, it indicates the update cannot be executed without being inconsistent (i.e. Fast Refresh bailed out), we would bail out to a forced reload.
To verify the impact of this change:
- Start a new project with CRA v4, update
App.js
with multiple exports (e.g. pmmmwh/react-refresh-webpack-plugin#426) - Run the project, try updating
App.js
with anything. Without this PR changes would not propagate on screen. - With this PR, the page should force refresh and propagate the changes.
To verify addendum to this change (error recovery):
- Using the same project, remove extra exports in
App.js
- Run the project, wait for the first compilation to complete
- Try adding a
throw new Error('no')
within theApp
component, compilation should show the error overlay - Try removing the error within the component,
App
should HMR properly without forced refresh - Try creating syntax errors within the module (e.g. remove quotation marks in imports), compilation should show the error overlay
- Try fixing the error,
App
should HMR properly without forced refresh
This should: Fixes #9904 (closed) Fixes #9913 (closed) Fixes #9984 (closed) Fixes Partially #10078 Fixes #10287 (closed) Fixes #10539 (closed) Fixes #10606 (closed) Fixes #11087 (closed)