Summary
With rsbuild-plugin-react-router@0.3.0 on Rsbuild 2 / Rspack 2, production builds intermittently-but-deterministically fail with:
File: static/js/virtual/react-router/browser-manifest.js:1:1
× Chunk minification failed:
╰─▶ × JavaScript parse error: Unexpected token `}`. Expected identifier
File: static/js/virtual/react-router/browser-manifest.js:1:1
× Chunk minification failed:
╰─▶ × JavaScript parse error: Unterminated string constant
Disabling minification (output.minify: false) lets the build finish, but inspecting the emitted file shows the manifest chunk is genuinely corrupted on disk (not just a minifier parsing quirk): the chunk's own runtime wrapper boilerplate (import { __webpack_require__ } from '../../runtime.js'; ... var __webpack_exec__ = ...) is spliced into the middle of the window.__reactRouterManifest = {...} string literal, multiple times, always cutting a JSON key/value pair mid-token. Total byte length of the file stays the same, so it looks like an in-place overwrite rather than a truncation.
Minimal reproduction
Fully isolated repro (no Module Federation, no custom server, no extra plugins) — just 13 routes generated with index/route/layout/prefix:
https://github.com/jaknas/rsbuild-plugin-react-router-manifest-corruption-repro
git clone https://github.com/jaknas/rsbuild-plugin-react-router-manifest-corruption-repro
cd rsbuild-plugin-react-router-manifest-corruption-repro
npm install
npm run build # fails with the minification error above
Toggle output.minify: false in rsbuild.config.ts to get the build to "succeed" and then inspect build/client/static/js/virtual/react-router/browser-manifest.js — you'll see __webpack_exec__(190) appear ~10 times inside what should be a single JSON-like string, e.g.:
...ack_chunk_1);\nvar __webpack_exports__ = __webpack_exec__(190);:{'id':'routes/section.;
},
};
import { __we...
Versions
rsbuild-plugin-react-router: 0.3.0
@rsbuild/core: 2.1.4
@rspack/core: 2.1.2 (transitive)
@rsbuild/plugin-react: 2.1.0
- node: v22.22.1
Bisection
- Reverting only
rsbuild-plugin-react-router to 0.1.1 (keeping @rsbuild/core/@rspack/core at 2.x) avoids the hard build failure — the plugin appears to not attempt minifying/re-processing this virtual asset the same way in that version.
- Reducing the route count in the reproduction below a certain threshold (roughly under ~10 routes in our testing) also avoids the corruption, which points to a size-triggered issue in how the large
window.__reactRouterManifest = {...} string is emitted/rendered as a chunk asset (possibly an Rspack-side bug in processAssets/chunk rendering for very long single-line ESM module bodies, surfaced here because this plugin is one of the few things that emits such a large single string literal into a chunk via compilation.updateAsset).
- On the pre-upgrade baseline (
@rsbuild/core 1.7.3 + @rspack/core 1.7.7 + rsbuild-plugin-react-router 0.1.1`), the equivalent build succeeds cleanly with an identical-sized route table.
Impact
This is a hard, deterministic production build failure for any app whose route table is large enough to push the generated manifest string past whatever the corruption threshold is (we hit it well before it seemed reasonable — a dozen or so routes). It blocked us from upgrading past rsbuild-plugin-react-router@0.1.1.
Happy to help debug further / test patches against our real app if useful.
Summary
With
rsbuild-plugin-react-router@0.3.0on Rsbuild 2 / Rspack 2, production builds intermittently-but-deterministically fail with:Disabling minification (
output.minify: false) lets the build finish, but inspecting the emitted file shows the manifest chunk is genuinely corrupted on disk (not just a minifier parsing quirk): the chunk's own runtime wrapper boilerplate (import { __webpack_require__ } from '../../runtime.js'; ... var __webpack_exec__ = ...) is spliced into the middle of thewindow.__reactRouterManifest = {...}string literal, multiple times, always cutting a JSON key/value pair mid-token. Total byte length of the file stays the same, so it looks like an in-place overwrite rather than a truncation.Minimal reproduction
Fully isolated repro (no Module Federation, no custom server, no extra plugins) — just 13 routes generated with
index/route/layout/prefix:https://github.com/jaknas/rsbuild-plugin-react-router-manifest-corruption-repro
Toggle
output.minify: falseinrsbuild.config.tsto get the build to "succeed" and then inspectbuild/client/static/js/virtual/react-router/browser-manifest.js— you'll see__webpack_exec__(190)appear ~10 times inside what should be a single JSON-like string, e.g.:Versions
rsbuild-plugin-react-router: 0.3.0@rsbuild/core: 2.1.4@rspack/core: 2.1.2 (transitive)@rsbuild/plugin-react: 2.1.0Bisection
rsbuild-plugin-react-routerto0.1.1(keeping@rsbuild/core/@rspack/coreat 2.x) avoids the hard build failure — the plugin appears to not attempt minifying/re-processing this virtual asset the same way in that version.window.__reactRouterManifest = {...}string is emitted/rendered as a chunk asset (possibly an Rspack-side bug inprocessAssets/chunk rendering for very long single-line ESM module bodies, surfaced here because this plugin is one of the few things that emits such a large single string literal into a chunk viacompilation.updateAsset).@rsbuild/core1.7.3 +@rspack/core1.7.7 +rsbuild-plugin-react-router0.1.1`), the equivalent build succeeds cleanly with an identical-sized route table.Impact
This is a hard, deterministic production build failure for any app whose route table is large enough to push the generated manifest string past whatever the corruption threshold is (we hit it well before it seemed reasonable — a dozen or so routes). It blocked us from upgrading past
rsbuild-plugin-react-router@0.1.1.Happy to help debug further / test patches against our real app if useful.