-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HMR for esbuild #464
Comments
HMR is often regarded as very difficult to get right. The over-engineering and complexity might be worth it in systems like webpack when a build takes a prohibitively long time each save, but in esbuild it should be fast enough that you can cut out that complexity and save yourself future headaches. There's some articles talking about this, like Dan's "Ode to Complexity" one. I can't speak for Evan but I personally don't know if I'd want to see this in esbuild... |
Yes that's how I feel as well. Closing as a duplicate of #97. FWIW I think facebook/react#16604 should be possible with the plugin API once that is released (you can follow #111 for updates). |
Quick note, HMR isn't just about dealing with build times, but also page load times and page state. Page load timeMost of the utility in HMR is in styling a page. If you're adding/removing classes from element generated by frameworks like React/Vue/etc. then the build may be super fast but to see your style updates you have to reload, which might be doing a number of async things like talking to oauth servers, loading data from local and remote APIs, etc. Would be nice to not have to wait on all of that just to see if your 2px of extra padding feels good. UI StateSometimes when you're styling your page is in a certain state, like the middle of a checkout flow where you don't want the state in the URL. HMR lets you get into the state, and then style your page. Anyway, excited to see a plugin, but I also think it'd be worth considering first-class support since HMR is about a lot more than build times. |
Yes but like I said the complexity to manage and reconcile your application state/styling/etc is highly framework specific - even app specific - and it doesn't really make sense for a bundler to make those opinionated decisions about HMR. Even other HMR implementations like webpack provide only a high level "accept"/"decline" API because you have to figure out the specifics or stay inline with an abstraction by a framework. I know it sounds easy but if you dive into it you'll see it gets messy fast. For instance, in the two cases you mentioned, styling isn't always a stylesheet replacement - popular frameworks like tailwind, emotion, and styled-components need compile-time and/or runtime updates that recompute style based on props and state of the entire render tree - assuming you have a render tree. Similarly, state isn't always something you can "get into" - I imagine you're thinking of a Redux-like system paired with a declarative React-like UI which will be happy to reconcile your DOM, but that's only one corner of web dev; if you're writing an imperative JS app whose state is just variables on the heap then how are you coordinating updates? Side effects and other "async things" are very hard to manage. Sometimes frameworks push ideas similar to functional/declarative/immutable programming which can help/offset this complexity - even to the point where HMR can be reasonable to implement. As a general purpose bundler, esbuild can't force users into any particular programming model. Even if esbuild could replace modules at runtime it wouldn't be as featureful compared to other framework-specific HMR options. |
I know what you mean and I want that too. In my framework the CSS-in-JS will recompute the hash for the classname and I'd need to rerender the DOM either way. I wish these things were easy haha. A quick low-tech solution is to use your dev tools to select the element and modify styles directly, then copy them out. |
Just stumbled over this thread and agree with both @heyheyhello and @ryanflorence. Looking at my build system which features webpack + webpack-dev-server is fragile. Now, it works flawlessly and having HMR in any FE-monorepo is great but I am also always afraid to change anything because it took me literally months to get there. It's easy to break HMR or anything else and hence, I have quite a long README about what to do and what not, the first time in a repo haha. For others driving by, I am wondering who omitted HMR and doesn't look back because of faster build times, etc. Before I jump into the next rabbit hole I'd like to do my due diligence and wonder how users deal with this restriction, maybe it's even better without. |
Oh I don't think it sounds easy at all, having messed around with HMR for a few years already 🥴 I was replying to the reasoning to not make HMR a first-class concept in esbuild:
If the reasoning for "no hmr" is that "fast builds make it unnecessary" I think that's missing the whole story. Page reloads in real apps pretty much always have async deps before the page renders. It's not about the bundler, it's about the page. If the reasoning is simply "it's just way too complicated", I can respect that. |
Maybe an unopinionated HMR API would look something like:
From there, maybe a React Refresh plugin author would do something like:
I don't really know if this would work or be a good experience. Really hard to predict without trying Its unfortunate that its not easy to serialize/deserialize react trees while preserving state/props. If that were possible, refresh would probably be a lot simpler |
For those who find this thread: it's now straightforward to add hot reloading of CSS on top of esbuild's new live reloading capability. This was just released in version 0.17.0. |
Dropping this here for anyone who runs across this and is looking to implement their own HMR runtime for esbuild: https://github.com/jacob-ebey/esbuild-hmr |
If esbuild could work with React Refresh, I'd abandon Vite |
Hi
Esbuild is amazing, i almost don't notice build process in contrast to webpack where i just waiting waiting and waiting...
Is it possible to add Hot module replacement ( or Fast Refresh now) for react in bundler ? Here is the process to include it in bundler facebook/react#16604.
The text was updated successfully, but these errors were encountered: