repack
repack copied to clipboard
Repack v3 HMR breaks React Native inspector/devtools
Environment
"@callstack/repack": "^3.0.0"
"react-native": "0.70.1"
node: v16.14.2
yarn: 1.22.19
Description
App throws error when attempting to access react native inspector (cmd+d) -> 'Show Inspector' and no inspection tools are available. After doing this the menu shows 'Hide Inspector' option and clicking this shows the same error.
Error in console:
[Console] Invariant Violation: Expected to find at least one React Native renderer on DevTools hook., js engine: hermes
Error on device:

Disabling HMR in webpack.config.js shows the inspector as expected.
Reproducible Demo
- Init a new react native project, for example:
npx react-native init test_app --template react-native-template-typescript - Configure Repack according to https://re-pack.netlify.app/docs/getting-started#dependencies, using updated webpack config template under v3: https://github.com/callstack/repack/blob/v3/templates/webpack.config.cjs.
- Run repack,
react-native webpack-startand runyarn ios --no-packager - Open simulator menu (cmd+d) and click 'Show Inspector', error shown and no inspector tools available.
- Restart repack with lines 47-49 uncommented (sets HMR to false), open menu and inspector works as expected.
Seems like this issue was related to @pmmmwh/react-refresh-webpack-plugin v0.5.
I found two solutions:
- lock
@pmmmwh/react-refresh-webpack-pluginto0.4.3by addingresolutionsto package.json:"resolutions": { "@pmmmwh/react-refresh-webpack-plugin": "^0.4.3" } - Modify
node_modules/react-devtools-core/dist/backend.js, searchinstallHookfunction and removetarget.hasOwnPropertycheck (first three lines.) And use patch-package to persistent changes.function installHook(target) { - if (target.hasOwnProperty('__REACT_DEVTOOLS_GLOBAL_HOOK__')) { - return null; - } var targetConsole = console; var targetConsoleMethods = {};
In my tests, downgrading to 0.4.3 made the initial webpack builds much slower - so that wasn't an option, unfortunately.
Removing the target.hasOwnProperty() check from backend.js also didn't work - that allowed connecting to dev tools but broke HMR.
I think this has something to do with the patch made in https://github.com/callstack/repack/pull/1 to initialize devtools before react-refresh. (Specifically this block here) It seems to no longer work with the latest version of @pmmmwh/react-refresh-webpack-plugin.
My solution:
In https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/0610d3c11ee54733612eb1a8a12400cf42ed24c7/lib/index.js#L75, use the legacy logic for injecting the plugin:
- if (EntryPlugin) {
+ if (false) {
// Prepended entries does not care about injection order,
// so we can utilise EntryPlugin for simpler logic.
addEntries.prependEntries.forEach((entry) => {
new EntryPlugin(compiler.context, entry, { name: undefined }).apply(compiler);
});
By doing this, the patch to re-arrange the plugin initialization order is able to correctly find the refresh plugin, because it hits this block instead:
} else {
compiler.options.entry = injectRefreshEntry(compiler.options.entry, addEntries);
}
There is probably a more correct way to do this (maybe change the code to find the react-refresh plugin to match the new EntryPlugin flow?), but I thought this would help point people down the right track.
Seems like this issue was related to
@pmmmwh/react-refresh-webpack-pluginv0.5.I found two solutions:
- lock
@pmmmwh/react-refresh-webpack-pluginto0.4.3by addingresolutionsto package.json:"resolutions": { "@pmmmwh/react-refresh-webpack-plugin": "^0.4.3" }- Modify
node_modules/react-devtools-core/dist/backend.js, searchinstallHookfunction and removetarget.hasOwnPropertycheck (first three lines.) And use patch-package to persistent changes.function installHook(target) { - if (target.hasOwnProperty('__REACT_DEVTOOLS_GLOBAL_HOOK__')) { - return null; - } var targetConsole = console; var targetConsoleMethods = {};
also check if all the .lock file has same version of ["@pmmmwh/react-refresh-webpack-plugin": "^0.4.3"]. Remove other version of react-refresh-webpack-plugin in .lock files. [in All Mini App also]