A module whose only page is Pages/Index.tsx (with the framework-required Pages/index.ts barrel doing () => import('./Index')) builds a broken bundle on macOS/Windows.
Repro (macOS or Windows)
- Module with single page
Pages/Index.tsx and barrel Pages/index.ts:
export const pages = { 'Foo/Index': () => import('./Index') };
vite build succeeds, no warnings.
- The lazy chunk emitted (
Index-<hash>.mjs) contains the barrel's content (~94 bytes), not the React component:
var pages = { "Foo/Index": () => import("./Index-<hash>.mjs") };
export { pages };
(recursive self-import)
- Runtime:
TypeError: Cannot assign to property 'layout' of [object Module] from resolveLayout — the lazy import returned the frozen entry namespace, not a component module.
Cause
Rolldown resolves import('./Index') to ./index.ts (the entry) on case-insensitive filesystems. The build silently produces a duplicated chunk. Workaround in consumer code is import('./Index.tsx') with explicit extension.
Fix options
defineModuleConfig rejects this combination at config-evaluation time with a clear error.
- Auto-rewrite extension-less imports inside
Pages/index.ts (similar to TypeScript module: "node16").
- Rename the framework barrel to something that can't collide (e.g.
Pages/_pages.ts).
The natural pattern for any module's "home" page IS Pages/Index.tsx, so this trap will catch every new framework adopter on Mac/Windows.
A module whose only page is
Pages/Index.tsx(with the framework-requiredPages/index.tsbarrel doing() => import('./Index')) builds a broken bundle on macOS/Windows.Repro (macOS or Windows)
Pages/Index.tsxand barrelPages/index.ts:vite buildsucceeds, no warnings.Index-<hash>.mjs) contains the barrel's content (~94 bytes), not the React component:TypeError: Cannot assign to property 'layout' of [object Module]fromresolveLayout— the lazy import returned the frozen entry namespace, not a component module.Cause
Rolldown resolves
import('./Index')to./index.ts(the entry) on case-insensitive filesystems. The build silently produces a duplicated chunk. Workaround in consumer code isimport('./Index.tsx')with explicit extension.Fix options
defineModuleConfigrejects this combination at config-evaluation time with a clear error.Pages/index.ts(similar to TypeScriptmodule: "node16").Pages/_pages.ts).The natural pattern for any module's "home" page IS
Pages/Index.tsx, so this trap will catch every new framework adopter on Mac/Windows.