vitejs / vitejs/vite-plugin-react
bundledDev: react-refresh preamble in entry chunk executes after shared chunks in MPA apps
@h-a-n-a is already working on this.
Since Jun 23, 2026.
- Dominant language
- TypeScript
- Stars
- 1.2k
- Forks
- 269
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 19
Description
Description
When using experimental: { bundledDev: true } with an MPA (appType: "mpa" and multiple HTML entries), the react-refresh preamble (which sets window.$RefreshReg$ and window.$RefreshSig$) is injected via transformIndexHtml in vite:react-refresh-fbm. During the Rolldown build, this becomes an html-proxy inline module in the entry chunk.
With multiple entry points, Rolldown's code splitting creates shared chunks containing component code. Due to ES module evaluation order (imports are evaluated depth-first), shared chunks execute before the entry chunk. The react-refresh-wrapper plugin's synchronous check for window.$RefreshReg$ in those shared chunks throws before the preamble has set it:
Uncaught Error: @vitejs/plugin-react can't detect preamble. Something is wrong.
This affects any MPA React app using bundledDev — Rolldown's default code splitting is sufficient to trigger it when modules are shared between entries, no custom codeSplitting.groups required.
Reproduction
// vite.config.ts
export default defineConfig({
appType: "mpa",
experimental: { bundledDev: true },
build: {
rolldownOptions: {
input: {
app: "entries/app/index.html",
other: "entries/other/index.html",
},
},
},
})
Both entries import any React component. The component ends up in a shared chunk, which executes before either entry's preamble.
Environment
vite: 8.0.8@vitejs/plugin-react: 6.0.0
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.