Skip to content

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

@hirish

Description

@hirish

Description

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

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

Rolldown tries to resolve /static/@react-refresh as a module specifier and fails, since the resolveId hook only matches the exact string /@react-refresh.

In non-bundled dev mode this works because the browser fetches it as a URL and Vite's baseMiddleware strips the prefix before the request reaches the resolve/load hooks. But in bundled dev mode, Rolldown resolves module specifiers at build time — there's no URL-level base stripping.

Reproduction

// vite.config.ts
export default defineConfig({
  base: "/static/",
  experimental: { bundledDev: true },
  // ...
})
[UNRESOLVED_IMPORT] Error: Could not resolve '/static/@react-refresh' in entries/app/index.html?html-proxy&index=0.js

Expected Behavior

The bundled dev mode preamble should use getPreambleCode("/") (or just "/@react-refresh" directly), since Rolldown resolves module specifiers, not URLs.

Environment

  • vite: 8.0.8
  • @vitejs/plugin-react: 6.0.0

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions