Faster reloading of isolated modules
Opened this issue · 2 comments
Currently, all isolated modules are reloaded between page requests. Additionally, this reloading does not take place until the next request comes in.
- We should reload eagerly (after each request, instead of before)
- We should reload only the modules that are stateful
- We need to build a module graph (really just the importers of each module) so we can reload selectively
The first solution that comes to mind is import.meta.hot
(Vite's HMR API). This is a flexible solution, as the user (and even plugins) can control how a module is reloaded, instead of only switching reload on/off. But it's also more verbose than, say, adding /* @hot */
at the top of the module, or managing a list of stateful modules from your Saus config (which I'd like to avoid, since the list can get out of sync).
I don't think we'll need to implement the entirety of Vite's HMR API. Just the basics for now.
We should reload only the modules that are stateful
-
When compiling ESM in current (unreleased) version of Saus, we already avoid top-level dependency destructuring if the dependency has mutable exports (eg:
export let
), so usingexport let
for "global state" is highly recommended if you want to reload as few modules as possible between requests (even if you never actually update theexport let
value). -
Assume a server module is stateful if…
- it contains an
export let
orexport var
statement - it exports a
new
expression likenew WeakMap()
with anexport const
statement - it uses an imported value from a stateful module at its top-level
- it contains an
Functions that mutate global state
If a server module contains an exported function that mutates global state referenced from an outer scope (not from an argument), you should export it with export let
to ensure the module is reloaded between requests. This is not necessary if the module in which this function exists is already stateful.
The first solution that comes to mind is
import.meta.hot
(Vite's HMR API).
Currently, "state modules" need special casing in the src/dev/hotReload
module. This feature will let us avoid that.