Reproduction
Failing integration test on the current main branch:
https://github.com/comp615/react-router/blob/5574f7ef87af726d1aedba2b2ed7520d71c40f3b/integration/bug-report-test.ts
The fixture configures Framework Mode with:
export default {
splitRouteModules: "enforce",
} satisfies Config;
and uses the standard React Router and React Vite plugins:
export default defineConfig({
plugins: [reactRouter(), react()],
});
The route has two otherwise independent JSX exports:
export function HydrateFallback() {
return <p>Loading...</p>;
}
export default function Index() {
return <h1>Ready</h1>;
}
Run:
pnpm install
pnpm build
pnpm test:integration:run bug-report --project chromium
The test first confirms that the production fixture build succeeds. Loading the same fixture through the Vite dev server then renders the error overlay:
Error splitting route module: routes/_index.tsx
- HydrateFallback
This export could not be split into its own chunk because it shares code with other exports.
System Info
System:
OS: macOS 26.5.2
CPU: (16) arm64 Apple M3 Max
Memory: 2.36 GB / 64.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 24.16.0
npm: 11.13.0
pnpm: 11.7.0
Browsers:
Chrome: 150.0.7871.125
Firefox: 152.0.5
Safari: 26.5.2
npmPackages:
@react-router/dev: workspace:* => 8.2.0
@react-router/fs-routes: workspace:* => 8.2.0
@react-router/serve: workspace:* => 8.2.0
@vitejs/plugin-react: ^6.0.1 => 6.0.1
react-router: workspace:* => 8.2.0
vite: ^8.0.0 => 8.0.2
Used Package Manager
pnpm
Expected Behavior
splitRouteModules: "enforce" should accept this route in Vite dev because the two exports do not share user-authored module-local code and the production build can split them successfully.
Actual Behavior
The React JSX development transform emits a shared module-level _jsxFileName binding used by the jsxDEV source metadata for both JSX exports. Dev manifest generation runs route-chunk dependency analysis on that transformed output, treats _jsxFileName as shared application code, and rejects HydrateFallback.
Production output does not contain the same development-only dependency, so the production build succeeds. This makes dev enforcement stricter than—and inconsistent with—the build output it is intended to enforce.
Potential directions include skipping build-only split enforcement during dev manifest generation, analyzing pre-development-JSX source, or excluding compiler-generated JSX source metadata from shared-binding analysis.
🤖 Report and reproduction prepared with AI assistance.
Reproduction
Failing integration test on the current
mainbranch:https://github.com/comp615/react-router/blob/5574f7ef87af726d1aedba2b2ed7520d71c40f3b/integration/bug-report-test.ts
The fixture configures Framework Mode with:
and uses the standard React Router and React Vite plugins:
The route has two otherwise independent JSX exports:
Run:
The test first confirms that the production fixture build succeeds. Loading the same fixture through the Vite dev server then renders the error overlay:
System Info
Used Package Manager
pnpm
Expected Behavior
splitRouteModules: "enforce"should accept this route in Vite dev because the two exports do not share user-authored module-local code and the production build can split them successfully.Actual Behavior
The React JSX development transform emits a shared module-level
_jsxFileNamebinding used by thejsxDEVsource metadata for both JSX exports. Dev manifest generation runs route-chunk dependency analysis on that transformed output, treats_jsxFileNameas shared application code, and rejectsHydrateFallback.Production output does not contain the same development-only dependency, so the production build succeeds. This makes dev enforcement stricter than—and inconsistent with—the build output it is intended to enforce.
Potential directions include skipping build-only split enforcement during dev manifest generation, analyzing pre-development-JSX source, or excluding compiler-generated JSX source metadata from shared-binding analysis.
🤖 Report and reproduction prepared with AI assistance.