vitejs / vite

Next generation frontend tooling. It's fast!
http://vitejs.dev
MIT License
67.2k stars 6.04k forks source link

Hot-module-replacement bubbling #207

Closed JoviDeCroock closed 4 years ago

JoviDeCroock commented 4 years ago

Is your feature request related to a problem? Please describe.

My feature request is related to Prefresh this enables fast-refresh for Preact.

We handle the hot-reloading of custom-hooks slightly different, instead of giving a custom-hook the hot.accept callback we rely on HMR bubbling this allows us to refresh the dependent components and compare the signatures of the full hooks-stack to determine if state can be kept or not.

A scenario, imagine we have a useCounter.js and a Counter.js component, when we update useCounter it will bubble up to Counter, now this component can decide whether or not it has to dispose all state, if it does have to dispose the state we can still just rerender with an update reference to useCounter instead of having to force a location.reload().

useCounter has explicitly bubbled up, marking it as in need of an update, this allows us to bubble up to Counter, this components re-requests itself, we see that it is importing a module in need of an update (useCounter in this case) and we rebuild the file.

I think this will also be needed for full custom-hook support in React fast-refresh.

Describe the solution you'd like

I've recently implemented this in snowpack and like how we solved it there, we define clear boundaries, these boundaries are hot.accept calls, when these are present we can stop bubbling but when a module doesn't have one we check if dependent modules are accepting HMR-signals and mark that module as in need of an update.

When we reach the end of a tree without accept calls we resort back to location.reload()

Additional context

This behavior is in line with how HMR behaves in traditional bundler setups.

yyx990803 commented 4 years ago

There is bubbling, I think there's some issue to be sorted out on how a self-accepting module is supposed to update. Let's track in https://github.com/vuejs/vite/issues/197