fix(vite): clear module runner cache before dev worker reload - #4473
Open
brenelz wants to merge 2 commits into
Open
fix(vite): clear module runner cache before dev worker reload#4473brenelz wants to merge 2 commits into
brenelz wants to merge 2 commits into
Conversation
|
@brenelz is attempting to deploy a commit to the Nitro Team on Vercel. A member of the Team first needs to authorize it. |
Contributor
📝 WalkthroughWalkthroughVite reloads now clear evaluated module state before re-importing the entry module. HMR fixtures and plugins reproduce dependency crawling and graph invalidation, while a regression test verifies updated API output and a full-reload message. ChangesVite reload cache handling
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related issues
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Member
|
Would be nice to add a regression test to vite-hmr fixture! |
commit: |
The dev worker's ViteEnvRunner.reload() re-imports the environment entry
without clearing the ModuleRunner's evaluatedModules cache. When a module's
transform is already populated on the Vite side at fetch time (for example
re-transformed by an assets crawl during the reload itself), fetchModule
answers {cache: true} and the runner reuses the stale evaluation, so the
server keeps executing old code until the dev server is restarted.
Vite's own full-reload handler clears evaluatedModules before re-importing;
do the same here.
The hmr fixture gains a dep-crawler plugin that re-transforms dep.ts as a
side effect of transforming api/crawled.ts (the way asset-collecting
plugins crawl imports), plus a plugin that hard-invalidates the server
module graph on dep.ts edits (as framework staleness workarounds do). On a
reload without evaluatedModules.clear(), the crawled transform makes
fetchModule answer {cache: true} for dep.ts and the stale evaluation is
served until restart — the new test fails without the fix and passes with
it.
brenelz
force-pushed
the
fix/vite-dev-worker-clear-evaluated-modules
branch
from
July 23, 2026 10:26
b6bcf72 to
1475302
Compare
This was referenced Jul 23, 2026
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.
🔗 Linked issue
Resolves item (3) of #4472. Same root cause as #4020 (closed, but the fix never landed). Related to #4043.
❓ Type of change
📚 Description
ViteEnvRunner.reload()in the dev worker re-imports the environment entry without clearing theModuleRunner'sevaluatedModulescache.The runner's
fetchModuleprotocol answers{cache: true}for any module whose transform is already populated on the Vite side at fetch time (packages/vite'sfetchModule:if (options.cached && cached) return { cache: true }). During a dev-worker reload, plugin-side crawls can repopulate transforms for large parts of the graph before the runner re-fetches them (observed with vite-plugin-solid's?assetstransform), so the re-import walks the entry but keeps stale evaluations for the very modules that changed — the server renders old code until the dev server is restarted, causing SSR/client hydration mismatches.Vite's own
full-reloadhandler in the module runner clearsevaluatedModulesbefore re-importing (hmrHandler.ts); this PR does the same in the worker'sreload().Verified against a Vite 8 + vite-plugin-solid SSR app: with this change (plus a
full-reloadactually being sent for shared modules — see #4472 items 1–2), edits to SSR-rendered modules are reflected on the next request without restarting the dev server, and hydration is clean.NITRO_DEBUG=1traces confirm all app modules re-execute after reload instead of being served from the stale cache.Includes a regression test in the
vite:hmrsuite: the fixture gains adep-crawlerplugin that re-transformsdep.tsas a side effect of transformingapi/crawled.ts(the way asset-collecting plugins crawl imports), plus a plugin that hard-invalidates the server module graph ondep.tsedits (as framework staleness workarounds do in the wild). WithoutevaluatedModules.clear()the crawled transform makesfetchModuleanswer{cache: true}fordep.tsand the test times out on the stale response; with the fix it passes.📝 Checklist