Skip to content

fix(plugin-react): use '/' base in bundledDev preamble to fix non-root base paths#1197

Open
JustInCache wants to merge 1 commit intovitejs:mainfrom
JustInCache:fix/bundled-dev-base-path
Open

fix(plugin-react): use '/' base in bundledDev preamble to fix non-root base paths#1197
JustInCache wants to merge 1 commit intovitejs:mainfrom
JustInCache:fix/bundled-dev-base-path

Conversation

@JustInCache
Copy link
Copy Markdown

@JustInCache JustInCache commented Apr 22, 2026

Summary

Fixes #1190

When using experimental: { bundledDev: true } with a non-root base (e.g. base: "/static/"), the vite:react-refresh-fbm plugin was calling getPreambleCode(base), producing:

import { injectIntoGlobalHook } from "/static/@react-refresh";

Rolldown resolves module specifiers at build time — there is no URL-level base-stripping middleware involved. So /static/@react-refresh never matched the resolveId hook which only handles the exact string /@react-refresh, causing:

[UNRESOLVED_IMPORT] Error: Could not resolve '/static/@react-refresh'

In non-bundled dev mode this worked because the browser fetched the URL and Vite's baseMiddleware stripped the prefix before the request reached the resolve/load hooks.

Fix

Pass '/' instead of config.base to getPreambleCode inside viteReactRefreshBundledDevMode. This produces /@react-refresh directly, which the resolveId hook can match. This is consistent with what virtualPreamblePlugin already does (with the comment "vite dev import analysis can rewrite base").

Test

Added a new e2e playground playground/bundled-dev-base-path with base: '/static/' + experimental: { bundledDev: true } that verifies:

  • The page loads without any UNRESOLVED_IMPORT browser errors
  • React renders and state updates work correctly

@JustInCache
Copy link
Copy Markdown
Author

@hi-ogawa Can you please review ? Suggest feedback if any !! Thanks

@hi-ogawa hi-ogawa requested a review from sapphi-red April 23, 2026 06:51
…t base paths

In bundled dev mode (`experimental.bundledDev: true`), Rolldown resolves
module specifiers at build time without any URL-level base stripping.
Using `config.base` in `getPreambleCode` produced an import like
`/@react-refresh` prefixed with the custom base (e.g. `/static/@react-refresh`),
which Rolldown couldn't resolve since the `resolveId` hook only matches
the exact string `/@react-refresh`.

Fix by passing `'/'` instead of `config.base` to `getPreambleCode` in the
`viteReactRefreshBundledDevMode` plugin, consistent with how
`virtualPreamblePlugin` already handles this case.

Fixes vitejs#1190

Made-with: Cursor
@JustInCache JustInCache force-pushed the fix/bundled-dev-base-path branch from e8c8bbe to d5a73d5 Compare April 23, 2026 06:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bundledDev: getPreambleCode uses config.base, breaking non-root base paths

1 participant