Skip to content

feat: allow HMR in server builds - #34

Merged
chenjiahan merged 1 commit into
rstackjs:mainfrom
OskarLebuda:feat/server-hot-reload
Sep 8, 2026
Merged

feat: allow HMR in server builds#34
chenjiahan merged 1 commit into
rstackjs:mainfrom
OskarLebuda:feat/server-hot-reload

Conversation

@OskarLebuda

Copy link
Copy Markdown

Follow-up to #32 (review) - the server HMR part of #32, with both issues you found fixed.

hotReload: true opts a server build into hot reload. Still a no-op without it, and hotReload: false keeps winning.

  • Template updates no longer call api.rerender(id, render) in a server build. render isn't imported there, and api.rerender can't take ssrRender either - it assigns whatever it gets to render and re-renders the mounted instances, which a server build doesn't have (only the DOM renderer registers them). The callback writes the new ssrRender back onto the component definition instead, which is the object parent modules hold on to.
  • The imported-type watch hook now invalidates serverCache as well, not just clientCache.

test/serverHotReload.spec.ts drives a watching server build: it renders through vue/server-renderer, edits a template / an imported type, applies the hot update the way a dev server would, and renders again. Both cases fail without the fixes above - render is not defined and stale props respectively.

`hotReload: true` now opts a server build into hot reload as well, so a dev
server that renders on the server can hot swap modules instead of restarting
the whole process. Server builds stay opt-in: without the flag nothing
changes, and `hotReload: false` still wins.

Addresses both issues raised in the review of rstackjs#32:

- A server build imports `ssrRender`, but the generated template update
  callback called `api.rerender(id, render)`, which threw
  `ReferenceError: render is not defined`. `api.rerender` cannot handle
  `ssrRender` either - it assigns whatever it is given to `render` and
  re-renders the mounted instances, which a server build does not have. The
  new function is written back to the component definition instead, which is
  the object parent modules hold on to.
- The imported-type watch hook only invalidated `clientCache`, so a server
  build kept rendering with the stale compiled script after an imported prop
  type changed. Both caches are invalidated now.

Tests drive a real watching server build: they render through
`vue/server-renderer`, edit a template or an imported type, apply the hot
update the way a dev server would, and render again.

@chenjiahan chenjiahan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

@chenjiahan
chenjiahan merged commit eac9a12 into rstackjs:main Sep 8, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants