I have an app where I dynamically import an HTML file and load that into the document. In version 3, changing the HTML file would trigger a refresh no problem, but in version 4 that no longer happens.
Interestingly it does recompile (the output changes to "Compiling..." for a moment) on save, but the new content is not available.
$ npm version
6.14.7
Fast refresh, hot reloading
$ npx create-react-app --info
npx: installed 98 in 5.514s
Environment Info:
current version of create-react-app: 3.4.1
running from /Users/kentcdodds/.npm/_npx/28053/lib/node_modules/create-react-app
System:
OS: macOS 10.15.6
CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
Binaries:
Node: 14.4.0 - ~/n/bin/node
Yarn: Not Found
npm: 6.14.7 - /usr/local/bin/npm
Browsers:
Chrome: 84.0.4147.135
Firefox: 77.0.1
Safari: 13.1.2
npmPackages:
react: ^16.13.1 => 16.13.1
react-dom: ^16.13.1 => 16.13.1
react-scripts: ^4.0.0-next.77 => 4.0.0-next.77
npmGlobalPackages:
create-react-app: Not Found
I'm still working on a simple way to reproduce. Will update this here soon.
I expect changing the file to trigger a refresh of the browser
Nothing on the page changes until I refresh the browser manually
https://github.com/kentcdodds/react-fundamentals
src/exercise/01.htmlAlrighty, here's a minimal reproduction. Pretty simple: https://github.com/kentcdodds/react-scripts-hot-reloading-raw-loader
// eslint-disable-next-line import/no-webpack-loader-syntax
import html from '!raw-loader!./example.html'
document.body.innerHTML = html
I realize that there is no intended support of raw-loader, so if this gets closed for that reason I guess I can accept that and I'll try to find a workaround. But it would be cool if we could find a way to get a refresh for this case.
I have had a quick look in the original mentioned repository and when I add a bunch of logs left and right. Looks like the change is detected but because the status of HMR is abort the status won't be applied as the line:
if (!isUpdateAvailable() || !canApplyUpdates()) {
is triggered so the function is exited because canApplyUpdated() returns false so it enters this if-block. I am not sure why the status is abort though.
Some of the logs which get triggered when changing the html file and then save it:
onmessage() message: {type: "invalid"}
webpackHotDevClient.js:207 onmessage() message: {type: "invalid"}
webpackHotDevClient.js:207 onmessage() message: {type: "invalid"}
webpackHotDevClient.js:207 onmessage() message: {type: "invalid"}
webpackHotDevClient.js:207 onmessage() message: {type: "hash", data: "8761994698881b8f5d7a"}
webpackHotDevClient.js:198 handleAvailableHash() 8761994698881b8f5d7a
webpackHotDevClient.js:207 onmessage() message: {type: "hash", data: "8761994698881b8f5d7a"}
webpackHotDevClient.js:198 handleAvailableHash() 8761994698881b8f5d7a
webpackHotDevClient.js:207 onmessage() message: {type: "ok"}
webpackHotDevClient.js:100 handleSuccess()
webpackHotDevClient.js:89 clearOutdatedErrors()
webpackHotDevClient.js:109 handleSuccess() isHotUpdate!!
webpackHotDevClient.js:248 tryApplyUpdates() onHotUpdateSuccess: 茠 onHotUpdateSuccess() {
// Only dismiss it when we're sure it's a hot update.
// Otherwise it would flicker right before the reload.
tryDismissErrorOverlay();
}
webpackHotDevClient.js:236 isUpdateAvailable()
webpackHotDevClient.js:257 tryApplyUpdates() isUpdateAvailable: true
webpackHotDevClient.js:242 canApplyUpdates() status: idle
webpackHotDevClient.js:258 tryApplyUpdates() canApplyUpdates: true
webpackHotDevClient.js:236 isUpdateAvailable()
webpackHotDevClient.js:242 canApplyUpdates() status: idle
webpackHotDevClient.js:207 onmessage() message: {type: "ok"}
webpackHotDevClient.js:100 handleSuccess()
webpackHotDevClient.js:89 clearOutdatedErrors()
webpackHotDevClient.js:109 handleSuccess() isHotUpdate!!
webpackHotDevClient.js:248 tryApplyUpdates() onHotUpdateSuccess: 茠 onHotUpdateSuccess() {
// Only dismiss it when we're sure it's a hot update.
// Otherwise it would flicker right before the reload.
tryDismissErrorOverlay();
}
webpackHotDevClient.js:236 isUpdateAvailable()
webpackHotDevClient.js:257 tryApplyUpdates() isUpdateAvailable: true
webpackHotDevClient.js:242 canApplyUpdates() status: abort
webpackHotDevClient.js:258 tryApplyUpdates() canApplyUpdates: false
webpackHotDevClient.js:236 isUpdateAvailable()
webpackHotDevClient.js:242 canApplyUpdates() status: abort
webpackHotDevClient.js:260 tryApplyUpdates() !isUpdateAvailable || !canApplyUpdates
webpackHotDevClient.js:236 isUpdateAvailable()
Following on from @weyert 's excellent detective work, here's the error that is causing the abort status:
Error: Aborted because ./node_modules/raw-loader/dist/cjs.js!./src/exercise/01.html is not accepted
Update propagation: ./node_modules/raw-loader/dist/cjs.js!./src/exercise/01.html -> ./src/index.js -> 1
at hotApplyInternal (bootstrap:558)
at hotApply (bootstrap:412)
at bootstrap:387
It could just be that as you theorize, raw-loader is not supported but I'm intrigued to have a little look further 馃憖
raw-loader was supported in previous versions, so if it's no longer supported that's either a regression or a breaking change. (Not a breaking change for CRA because technically inline loaders isn't supported. I mean a breaking change for raw-loader or webpack).
a little workaround is to use this
if (module.hot) {
module.hot.accept()
}
in your index.js file
Maybe the problem is causing by the new webpack plugin that CRA is using fast-refresh
Considering inline loaders aren't technically supported, that's a satisfactory solution. Thanks @marcofugaro!
Most helpful comment
I have had a quick look in the original mentioned repository and when I add a bunch of logs left and right. Looks like the change is detected but because the status of HMR is
abortthe status won't be applied as the line:is triggered so the function is exited because canApplyUpdated() returns false so it enters this if-block. I am not sure why the status is
abortthough.Some of the logs which get triggered when changing the html file and then save it: