fix(plugin-rsc): use MagicString to preserve sourcemap chain in webpack-require transform#1120
fix(plugin-rsc): use MagicString to preserve sourcemap chain in webpack-require transform#1120nianyi778 wants to merge 3 commits intovitejs:mainfrom
Conversation
|
Can you provide reproduction? |
@hi-ogawa
Root cause in one sentence: The rsc:patch-react-server-dom-webpack transform replaces webpack_require (18 chars) with vite_rsc_require (20 chars) — a non-same-length substitution — and returns map: null, which breaks the Rollup sourcemap chain for every downstream file. |
|
Alright, thanks. Can reproduce right here with $ pnpm -C packages/plugin-rsc/examples/starter build --sourcemap
> @vitejs/plugin-rsc-examples-starter@0.0.0 build /home/hiroshi/code/others/vite-plugin-react/packages/plugin-rsc/examples/starter
> vite build --sourcemap
[1/5] analyze client references...
vite v7.3.1 building rsc environment for production...
✓ 55 modules transformed.
[plugin rsc:virtual:vite-rsc/assets-manifest] Sourcemap is likely to be incorrect: a plugin (rsc:virtual:vite-rsc/assets-manifest) was used to transform files, but didn't generate a sourcemap for the transformation. Consult the plugin documentation for help
✓ built in 256ms
[2/5] analyze server references...
vite v7.3.1 building ssr environment for production...
✓ 50 modules transformed.
[plugin rsc:virtual:vite-rsc/assets-manifest] Sourcemap is likely to be incorrect: a plugin (rsc:virtual:vite-rsc/assets-manifest) was used to transform files, but didn't generate a sourcemap for the transformation. Consult the plugin documentation for help
✓ built in 250ms
[3/5] build rsc environment...
vite v7.3.1 building rsc environment for production...
✓ 55 modules transformed.
[plugin vite:reporter]
(!) /home/hiroshi/code/others/vite-plugin-react/packages/plugin-rsc/examples/starter/src/action.tsx is dynamically imported by virtual:vite-rsc/server-references but also statically imported by /home/hiroshi/code/others/vite-plugin-react/packages/plugin-rsc/examples/starter/src/root.tsx, dynamic import will not move module into another chunk.
[plugin rsc:inject-async-local-storage] Sourcemap is likely to be incorrect: a plugin (rsc:inject-async-local-storage) was used to transform files, but didn't generate a sourcemap for the transformation. Consult the plugin documentation for help
[plugin rsc:inject-async-local-storage] Sourcemap is likely to be incorrect: a plugin (rsc:inject-async-local-storage) was used to transform files, but didn't generate a sourcemap for the transformation. Consult the plugin documentation for help (x2)
[plugin rsc:virtual:vite-rsc/assets-manifest] Sourcemap is likely to be incorrect: a plugin (rsc:virtual:vite-rsc/assets-manifest) was used to transform files, but didn't generate a sourcemap for the transformation. Consult the plugin documentation for help
dist/rsc/assets/react-CHdo91hT.svg 4.13 kB
dist/rsc/assets/index-NeOOZrmx.css 1.40 kB
dist/rsc/index.js 626.79 kB │ map: 14.28 kB
✓ built in 585ms
[4/5] build client environment...
vite v7.3.1 building client environment for production...
✓ 42 modules transformed.
[plugin rsc:vite-client-raw-import] Sourcemap is likely to be incorrect: a plugin (rsc:vite-client-raw-import) was used to transform files, but didn't generate a sourcemap for the transformation. Consult the plugin documentation for help
dist/client/assets/react-CHdo91hT.svg 4.13 kB │ gzip: 2.05 kB
dist/client/assets/index-NeOOZrmx.css 1.40 kB │ gzip: 0.71 kB
dist/client/assets/entry.rsc-JZAVNEuk.js 0.27 kB │ gzip: 0.24 kB │ map: 0.59 kB
dist/client/assets/index-DPERZMr6.js 222.96 kB │ gzip: 70.55 kB │ map: 1,034.11 kB
✓ built in 477ms
[5/5] build ssr environment...
vite v7.3.1 building ssr environment for production...
✓ 51 modules transformed.
[plugin rsc:virtual:vite-rsc/assets-manifest] Sourcemap is likely to be incorrect: a plugin (rsc:virtual:vite-rsc/assets-manifest) was used to transform files, but didn't generate a sourcemap for the transformation. Consult the plugin documentation for help
[plugin rsc:inject-async-local-storage] Sourcemap is likely to be incorrect: a plugin (rsc:inject-async-local-storage) was used to transform files, but didn't generate a sourcemap for the transformation. Consult the plugin documentation for help
[plugin rsc:inject-async-local-storage] Sourcemap is likely to be incorrect: a plugin (rsc:inject-async-local-storage) was used to transform files, but didn't generate a sourcemap for the transformation. Consult the plugin documentation for help (x2)
[plugin rsc:virtual:vite-rsc/assets-manifest] Sourcemap is likely to be incorrect: a plugin (rsc:virtual:vite-rsc/assets-manifest) was used to transform files, but didn't generate a sourcemap for the transformation. Consult the plugin documentation for help
dist/ssr/assets/entry.rsc-DMKK0oJ_.js 0.54 kB │ map: 0.12 kB
dist/ssr/index.js 1,560.08 kB │ map: 32.68 kB
✓ built in 716ms |
|
Added unit tests in 9909dbd. Extracted the transform logic into an exported Added 6 test cases covering:
All tests pass (63 total). Side note: the build output also shows “Sourcemap is likely to be incorrect” from:
These appear to be the same class of issue (transforms not returning proper sourcemaps). Happy to address those in a follow-up PR if that makes sense. |
hi-ogawa
left a comment
There was a problem hiding this comment.
Unit test is not needed. Please add e2e.
…ck-require transform The rsc:patch-react-server-dom-webpack transform replaces __webpack_require__ (18 chars) with __vite_rsc_require__ (20 chars) — a non-same-length substitution — and previously returned map: null, which broke the Rollup sourcemap chain. Replace the manual replaceAll + map: null with MagicString, which generates a correct hires sourcemap reflecting the actual offset changes. Added e2e test that builds the starter example with --sourcemap and verifies no sourcemap warnings are emitted for this transform.
9909dbd to
b620e6c
Compare
|
Replaced unit tests with e2e test in
|
hi-ogawa
left a comment
There was a problem hiding this comment.
The test added in this PR doesn't seem to fail on main. This doesn't serve as a test to verify the fix. Can you find proper reproduction?
The previous e2e test didn't fail on main because `map: null` doesn't trigger Vite's 'Sourcemap is likely to be incorrect' warning — it silently breaks the sourcemap chain. The new vitest directly verifies the transform returns a valid sourcemap (not null) with non-empty mappings, which fails on main (3 failures) and passes with the fix.
|
You're right — the e2e test couldn't fail on main because Replaced the e2e test with a vitest in On main — 3 failures ( With fix — all 61 tests pass (including the 4 new ones). |
Problem
The
rsc:patch-react-server-dom-webpacktransform replaces__webpack_require__occurrences using string operations and returns{ code, map: null }. Returningmap: nullfrom a transform that changes string lengths breaks the Rollup sourcemap chain, causing Rollup/Vite to emit a noisy warning for every file that passes through this transform:In practice this fires for every
"use client"component in an app, since those files go through the RSC pipeline and may contain (or transitively load) modules that match the__webpack_require__filter. The build still succeeds, but the output is very noisy.Root cause:
__webpack_require__(18 chars) →__vite_rsc_require__(20 chars) is not a same-length replacement, somap: nulldoesn't just "suppress" the map — it actively misleads Rollup about character offsets, snapping the sourcemap chain.Fix
Replace the manual
replaceAll+map: nullwith MagicString, which:hiressourcemap that reflects the actual offset changes.__webpack_require__.uvariant and bare__webpack_require__in a single left-to-right regex pass (avoids overlapping overwrites)magic-stringis already a dependency of this package.Testing
Verified with a Next.js + vinext (Cloudflare Workers) app: the 10+ sourcemap warnings on every
"use client"component are eliminated with this fix applied.