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

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions