Skip to content

Commit 29b2b9d

Browse files
authored
feat: add reloadOnRuntimeErrors config (#50)
1 parent dbaf852 commit 29b2b9d

File tree

4 files changed

+33
-0
lines changed

4 files changed

+33
-0
lines changed

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,21 @@ new ReactRefreshPlugin({
217217
});
218218
```
219219

220+
### reloadOnRuntimeErrors
221+
222+
- Type: `boolean`
223+
- Default: `false`
224+
225+
Config the plugin whether trigger a full page reload when an unrecoverable runtime error is encountered.
226+
227+
Currently, only module factory undefined error is considered as unrecoverable runtime error.
228+
229+
```js
230+
new ReactRefreshPlugin({
231+
reloadOnRuntimeErrors: true,
232+
});
233+
```
234+
220235
## Credits
221236

222237
Thanks to the [react-refresh-webpack-plugin](https://github.com/pmmmwh/react-refresh-webpack-plugin) created by [@pmmmwh](https://github.com/pmmmwh), which inspires implement this plugin.

client/refreshUtils.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ function shouldInvalidateReactRefreshBoundary(prevExports, nextExports) {
209209
}
210210

211211
var enqueueUpdate = createDebounceUpdate();
212+
212213
function executeRuntime(
213214
moduleExports,
214215
moduleId,
@@ -246,6 +247,12 @@ function executeRuntime(
246247
*/
247248
function hotErrorHandler(error) {
248249
console.error(error);
250+
if (
251+
__reload_on_runtime_errors__ &&
252+
isUnrecoverableRuntimeError(error)
253+
) {
254+
location.reload();
255+
}
249256

250257
if (typeof refreshOverlay !== 'undefined' && refreshOverlay) {
251258
refreshOverlay.handleRuntimeError(error);
@@ -289,6 +296,10 @@ function executeRuntime(
289296
}
290297
}
291298

299+
function isUnrecoverableRuntimeError(error) {
300+
return error.message.startsWith('RuntimeError: factory is undefined');
301+
}
302+
292303
module.exports = Object.freeze({
293304
enqueueUpdate: enqueueUpdate,
294305
executeRuntime: executeRuntime,

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ class ReactRefreshRspackPlugin {
106106
compiler.options.output.library,
107107
),
108108
),
109+
__reload_on_runtime_errors__: this.options.reloadOnRuntimeErrors,
109110
};
110111
const providedModules: Record<string, string> = {
111112
__react_refresh_utils__: refreshUtilsPath,

src/options.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ export type PluginOptions = {
7979
* @default true
8080
*/
8181
injectEntry?: boolean;
82+
/**
83+
* Whether to reload the page on runtime errors. E.g: undefined module factory
84+
* @default false
85+
*/
86+
reloadOnRuntimeErrors?: boolean;
8287
};
8388

8489
export interface NormalizedPluginOptions extends Required<PluginOptions> {
@@ -128,6 +133,7 @@ export function normalizeOptions(
128133
d(options, 'forceEnable', false);
129134
d(options, 'injectLoader', true);
130135
d(options, 'injectEntry', true);
136+
d(options, 'reloadOnRuntimeErrors', false);
131137
options.overlay = normalizeOverlay(options.overlay);
132138
return options as NormalizedPluginOptions;
133139
}

0 commit comments

Comments
 (0)