feat(bundled-dev): support hotUpdate and handleHotUpdate hook#22956
Open
h-a-n-a wants to merge 1 commit into
Open
feat(bundled-dev): support hotUpdate and handleHotUpdate hook#22956h-a-n-a wants to merge 1 commit into
hotUpdate and handleHotUpdate hook#22956h-a-n-a wants to merge 1 commit into
Conversation
h-a-n-a
force-pushed
the
feat/client-side-hmr
branch
2 times, most recently
from
July 21, 2026 03:49
3082b1b to
d4ba516
Compare
Base automatically changed from
feat/client-side-hmr
to
renovate/rolldown-related-dependencies
July 21, 2026 13:35
h-a-n-a
force-pushed
the
feat/hot-update
branch
2 times, most recently
from
July 22, 2026 12:57
ae0a77c to
1030097
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Makes Vite's
hotUpdateandhandleHotUpdateplugin hooks work in bundled dev. Built on top of rolldown's new dev-onlyhotUpdatehook (rolldown/rolldown#10305).Problem
In bundled dev, the rolldown engine owns the module graph and the update flow. When a file changes, hooks run inside the engine, and the engine speaks plain module ids. But Vite plugins expect Vite's types:
EnvironmentModuleNodeobjects, amoduleGraph, and a shared context per event. Without a bridge, every plugin that uses these hooks does nothing in bundled dev.Design
Two pieces, both new in
bundledDevHmr.ts:BundledModuleGraph). The engine owns the real graph. The facade creates a Vite module node on demand for each id, and creates it only once — plugins compare nodes by reference and store state on them, so identity matters. A node'sinfo,importers, andimportedModulesare read live from the engine, so they stay correct after every rebuild without any bookkeeping. Writes to nodes do nothing, because the engine owns the graph.BundledDevHotUpdateAdapter). Each Vite plugin with either hook gets its own wrapper, registered as that plugin's rolldownhotUpdatehook. So plugin order and the replace-chain rules come from rolldown's own driver — the adapter does not re-implement them. The wrapper translates ids to nodes on the way in, and nodes back to ids on the way out.The main design rules:
applyToEnvironmentis a rolldown plugin. ItshotUpdatealready expects ids and must stay unwrapped.file.vue?type=styleare included). All wrappers for that file share one options object, so a change made by one plugin (for example a reassignedread) is visible to the next. A post-ordered hook merges modules buffered withmoduleGraph.invalidateModuleand closes the state.invalidateAllmeans full rebuild plus page reload. That is the closest match to its meaning in bundled dev.handleHotUpdategets the sharedHmrContextwith mixed module nodes, fires only for updates, and warns about its deprecation.Tests
End-to-end coverage lives in the rolldown repo's dev-server test suite (
hmr-hot-update-hook-vite, 8 browser specs). It covers the common plugin patterns: replacing the set, invalidate buffering (tailwind style), custom messages withread()andhot.send(markdown-pages style), the legacy shared-contextreadchain (unocss with plugin-vue), file-to-submodule expansion (SFC style), suppress, andinvalidateAll. Unit tests in this repo are planned as a follow-up.