Skip to content

@vitejs/plugin-react 'can't detect preamble' on module-shipped .tsx pages #66

Description

@antosubash

Summary

@vitejs/plugin-react raises "can't detect preamble. Something is wrong." for any module-shipped .tsx page (i.e. files served from outside host/client_app/).

Module pages live either in:

  • modules/<m>/lacowiki_<m>/pages/Login.tsx (workspace member), or
  • .venv/lib/python3.12/site-packages/<m>/pages/Login.tsx (wheel-installed)

Vite's dev server is configured with server.fs.allow to read these (the bundled vite.config.ts does this correctly). But @vitejs/plugin-react's React Fast Refresh preamble is only injected into the host's index.html. When the .tsx is served via Vite's /@fs/ mechanism from outside client_app/, the per-component preamble check fires before the entry-point preamble has executed in the same JS realm, and the plugin throws.

Reproduction

  1. Scaffold a host with sm new --preset full.
  2. Install any framework module that ships pages (e.g. simple_module_users ships Login.tsx from its wheel).
  3. npm run dev.
  4. Navigate to /login. Console:
    Error: @vitejs/plugin-react can't detect preamble. Something is wrong.
        at http://localhost:5050/@fs/.../site-packages/users/pages/Login.tsx:277:11
    
    White screen.

Workarounds I've tried

  • Clearing .vite cache → no change.
  • Adding optimizeDeps.include for the user-facing entry → no change.
  • Hard reload → no change. Issue is consistent.

Suggested investigation

The host's main.tsx already wraps Inertia setup with createRoot(). The plugin's preamble is sourced from __vite_plugin_react_preamble_installed__ on globalThis. When the cross-origin .tsx is loaded via /@fs/, the realm matches but the load order may race. Possibly the React plugin needs include configured for the absolute paths in server.fs.allow, or the host scaffold should enable fastRefresh: false for non-host paths.

A working test would be: configure react() plugin to skip Fast Refresh entirely for files outside __dirname, or ship the host's main.tsx with a manual preamble bootstrap.

Impact

This blocks the entire dev server for any host that consumes module-shipped pages — which is every real installation, since simple_module_users ships Login.tsx and all --preset full hosts use it.

Environment

  • vite@6.4.2, @vitejs/plugin-react@5.x
  • simple_module_users page served from .venv/lib/python3.12/site-packages/users/pages/Login.tsx
  • Discovered while building laco_wiki_python rewrite

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions