Open aspcartman opened 1 year ago
+1, hot reload / HMR has many problems โย including sometimes crashing the entire page (#8615).
+1
We have hacked this together the following way in our code because parcel doesn't reload the page for CSS changes when making a library build (https://github.com/parcel-bundler/parcel/issues/6506). It works because parcel always calls console.clear
on HMR. You'll have to adapt it for your use-case
if (process.env.NODE_ENV === "development") {
console.clear = new Proxy(console.clear, {
apply(target, this_arg, arg_list) {
if (
new Error().stack
?.split("\n")
.filter(Boolean)
.some(s => s.includes("http://localhost:1234/PARCEL-DEV-URL.js"))
) {
/* eslint-disable no-console */
console.log("CSS change detected through hack, reloading");
location.reload();
}
return target.apply(this_arg, arg_list);
},
});
}
Reloading the page is the default, but some frameworks provide a built in HMR handler. React Refresh is one of those. If you want to opt out of that, you can remove the plugin by reconfiguring the pipeline for JS/TS files in your .parcelrc
:
{
"extends": "@parcel/config-default",
"transformers": {
"*.{js,jsx,ts,tsx}": ["@parcel/transformer-js"]
}
}
This overrides the default pipeline which includes @parcel/transformer-react-refresh-wrap
. Without that, React Refresh won't be loaded and no HMR handlers will be registered so it should fall back to reloading the page.
When using Parcel 2 with React, will it only try to use React's Fast Refresh, or will it fall back to a page reload? I'm updating from Parcel 1 (where it will reload the page on changes) to Parcel 2 and the CSS hot reloading works, but nothing updates or reloads when making changes to React components and I'm not sure why.
It's possible the app is not fully compatible with Fast Refresh, but changing everything just for that is out of the scope of what I'm doing right now. I'm fine with page reloads for now, but nothing is happening. When I update a React component, the only thing I see happen in the browser is the console getting cleared.
Update: I'm not sure getting the app fully compatible with Fast Refresh is even possible right now. According to the Parcel tips for using Fast Refresh, you can only use it with function components, but hooks do not cover all use cases, and we have a top-level component that can't be switched yet. Does this mean Parcel won't do any automatic reloading when our React components change?
Reloading the page is the default, but some frameworks provide a built in HMR handler. React Refresh is one of those. If you want to opt out of that, you can remove the plugin by reconfiguring the pipeline for JS/TS files in your
.parcelrc
:{ "extends": "@parcel/config-default", "transformers": { "*.{js,jsx,ts,tsx}": ["@parcel/transformer-js"] } }
This overrides the default pipeline which includes
@parcel/transformer-react-refresh-wrap
. Without that, React Refresh won't be loaded and no HMR handlers will be registered so it should fall back to reloading the page.
This is the @parcel/config-default transformer.
I believe that instead of just ["@parcel/transformer-js"]
we want "*.{js,mjs,jsm,jsx,es6,cjs,ts,tsx}": [ "@parcel/transformer-babel", "@parcel/transformer-js", ]
? (to have the -babel
at first)
This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs.
๐ feature request
Mention a possible force opt-out of HRM in documentation, that would guarantee a classic dev-server behavior: any file change -> page reload.
๐ค Expected Behavior
According to the official documentation page, HMR is not active until
module.hot.accept
is explicitly called. That reads as "ok if I do not put the provided snippet to my code it will just work as usual - reload the whole page on any change".๐ฏ Current Behavior
parcel serve
reports on rebuild, but the page is not reloaded.--no-hmr
flag doesn't help.window.location.reload()
callback in theaccept()
call leds to reloads on some files change, but most - still don't work.๐ Possible Solution
Mention on the same documentation page a force-opt-out. I figured it by is possible to:
Yet the
parcelhmraccept
is not a public api symbol and might change in the future - not clear if ok to be mentioned in the docs. A better alternative might be an explicitmodule.hot.forcePageReloads()
api. Even more better - make--no-hmr
force reload page on any file change that triggered the rebuild.๐ฆ Context
The real project I'm working on is a Preact single-page app. During my investigation I've found that:
@parcel/transformer-react-refresh-wrap
does wrap preact components - seems to be an undesired behavior with unclear consequences. All components in the project ends up wrapped in the dev bundle.module.hot
at will - unclear if that 'opts-in' HRM, as the current documentation states. I don't see any 'opt-in' logic in the parcel output bundle though.--no-hmr
does something unobvious, where the obvious seems to be "disable hot module reload, reload the whole page instead".Reloading the page upon a code change is an expected default behaviour of a development web server and it's quite possible that people facing such an issue during the adopt process of Parcel might stop their trial just there.
BTW: Should I fill a bug report on
@parcel/transformer-react-refresh-wrap
?