Repository navigation
fix(router): per-app cache versions ignore rolldown 1.2.15's module markers; vite 8.3.5 (rango-t228) - #1320
Merged
Conversation
…le markers (rango-t228, red) rolldown 1.2.15 (rolldown/rolldown#11235, installed by vite 8.2 and later) prints `// <module id>` where each module starts instead of wrapping it in `//#region <id>` / `//#endregion`. The version hashing only knows the region form, so the module paths stay in the hash and the server-reference map is hashed whole. Three tests fail on this commit: - a chunk digests differently when its start-only markers are relative to another directory; - the server-reference map's body is not dropped under a start-only marker; - a router's version moves when another app adds a server action. Two guards pass already and must keep passing: a `// ` line that names no module of its chunk is hashed, and a map no marker follows is kept.
…arkers (rango-t228) rolldown 1.2.15 (rolldown/rolldown#11235), which a fresh install of vite 8.2 or later resolves to, prints `// <id>` before each module of an unminified chunk instead of wrapping it in `//#region <id>` and `//#endregion`. digestBundle stripped only the region form, so on the new rolldown: - the module paths stayed in the hashed text: a build started from another directory gave every router new versions, and a checkout at another path did so for each router with a CSS-importing server component (the virtual css id prints the absolute path in its query); - stripServerReferenceMap found no region and kept plugin-rsc's server-reference map, so a new action in one app moved every app's versions. stripServerReferenceMap now finds the map's marker in either form and ends its body at the next marker. stripModulePaths (was stripRegionPaths) blanks every `//#region` path, and a `// ` line only when it names a module of the chunk, as rolldown prints it relative to its working directory, so a kept comment or a line of a template literal stays hashed. A minified build, or a map no marker follows, keeps the old behavior of hashing more. The repo moves to vite ^8.3.5 (catalog and overrides; lockfile resolves vite 8.3.5 and rolldown 1.2.15). The peer range stays ^8.0.16: the real- build suite passes on vite 8.0.16, 8.1.6 and 8.3.5.
This was referenced Oct 28, 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.
devcorner: rango-t228 · session rango-s448
On rolldown 1.2.15, unchanged source builds to the same per-app cache versions in any directory again, and one app's new server action no longer changes the other apps' versions. Any fresh install of vite 8.2 or later resolves that rolldown. The repo moves to vite 8.3.5, which replaces Dependabot's #1222. The peer range stays
vite: ^8.0.16.Problem
vite buildgives each app a data version and a document version, and the deploy keeps the caches of every app whose versions did not change (docs/design/per-app-cache-version.md). The versions hash the server output after taking out what describes the build rather than the code. That includes the module path the bundler prints above each module.rolldown 1.2.15 (rolldown/rolldown#11235) changed that comment. It used to wrap each module in
//#region <id>…//#endregion; now it prints only// <id>where the module starts. The hashing only knew the region form, so on vite 8.2 and later:vite buildfrom another directory gave every app new versions. Building it from a checkout at another path did the same for every app with a server component that imports CSS: plugin-rsc's CSS module id prints the absolute path. Each such deploy threw away caches that were still valid.#1222 showed it: 11 of 22 tests in
cache-versions-build.test.tsfailed. Its title says vite 8.1.6, but its lockfile resolved vite 8.3.5 with rolldown 1.2.15. vite 8.1.6 depends on rolldown~1.1.5, which is not affected.Before and after, for a consumer
The same two builds of the same commit, one in the app and one from the repository root:
Before, on vite 8.2+: build 2 baked other data and document versions into every app, so deploying it cleared every app's cache.
After: both builds bake in the same versions, as they do on vite 8.0 and 8.1.
No consumer code changes.
Semantics
//comment or string line that names no module of its chunkCode changes
packages/rangojs-router/src/vite/discovery/build-versions.ts:stripServerReferenceMapfinds the map's marker in either form and drops its body up to the next//line or//#endregion:stripRegionPathsbecomesstripModulePaths(source, chunk.moduleIds). A//#regionline is always a marker, as before. A//line is blanked only when it names one of the chunk's own modules as rolldown prints it: relative to its working directory, so some../and then a trailing run of the path's segments, or a virtual id with\0printed as two characters. A kept comment or a line of a multi-line string that happens to start with//stays in the hash, which only clears more.The fix stays in the hash input, not the output. rolldown's
experimental.attachDebugInfo: "none"would remove the markers, but it changes the shipped bytes. It also removes the marker that bounds the server-reference map, which would put the map back into every hash. Hashing the per-module code fromgenerateBundleinstead would miss the chunk's import and export lines and anythingpostprocessBundlewrites afterwards.Other files:
pnpm-workspace.yaml: catalog and overrides go tovite: ^8.3.5. The lockfile changes only vite 8.3.5 and what it pulls in: rolldown 1.2.15, lightningcss 1.33.0, postcss 8.5.32, @oxc-project/types 0.155.0, nanoid, picomatch and source-map-js, plus the peer-suffix renames.docs/design/per-app-cache-version.mddescribes both marker forms;CHANGELOG.mdgets an Unreleased Fixed entry.Test plan
Red before green.
cache-versions-build.test.ts(real builds): 11 failed, 11 passed.f289608e1) against main's code: 3 failed, 76 passed. The failures are:With the fix,
build-versions.test.tsandcache-versions-build.test.tspass, 102/102, on vite 8.0.16, 8.1.6 and 8.3.5. After the review cleanup they were re-run on 8.3.5: 102/102. The region-form unit tests pin the older form.New unit tests in
build-versions.test.ts. Each pins a contract://lines are kept.//line that names no module of its chunk is hashed.pnpm run typecheck,pnpm run test:unit:all,pnpm run lint,pnpm run format.Every
check:*script, includingcheck:e2e-parity --strict,check:suspense-contract,check:internalsandcheck:route-gen(no.gen.tschanges).check:bundle-guards: pass. The router chunk is 52025 B gzip, down from 52279 B on main, under the 52352 B cap. The change comes from the rolldown bump; this code is build-time only.node --teston thetoolstests: 63/63.Targeted e2e on vite 8.3.5, before the review cleanup. The cleanup changed only the hashing code that the unit tests above cover.
The cache-version suites have production describes only, by design: versions exist only after
vite build.CI's full e2e run on this head.
Notes
__dirnameatpackages/rangojs-router/vitest.config.ts:29and an import without an extension attests/cloudflare-basic/vite.config.ts:8. Nothing fails. It is outside this PR.Practices
pnpm run lint,pnpm run formatand everycheck:*script passed on the head.SERVER_REFERENCES_REGION_START,REGION_END,REGION_LINE) andstripRegionPathsare gone. No references remain.//#regionline blanked without a module check, as on main, so builds on vite 8.0 and 8.1 hash exactly as before;docs/design/per-app-cache-version.md, "What is hashed"; CHANGELOG.