Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix: unwrap namespace.default in prebuild named-exports branch#870

Merged
gioboa merged 1 commit into
module-federation:mainfrom
muiradams:fix/prebuild-default-export-cjs-interop
Jul 2, 2026
Merged

fix: unwrap namespace.default in prebuild named-exports branch#870
gioboa merged 1 commit into
module-federation:mainfrom
muiradams:fix/prebuild-default-export-cjs-interop

Conversation

@muiradams

Copy link
Copy Markdown
Contributor

Summary

Fixes a CJS-interop default-export bug in the writePreBuildLibPath codegen for shared modules.

The branch selected when a shared package has any named exports emits:

import * as __mfPrebuildNamespace from '<pkg>';
const __mfPrebuildExports = __mfPrebuildNamespace;
...
export default __mfPrebuildExports;   // ← the raw namespace object

But the three sibling branches in the same function — react/jsx-runtime, react/jsx-dev-runtime, and the fallback for packages with no named exports — all use namespace.default ?? namespace. This was inconsistent codegen and caused a real interop regression for consumers.

Impact

For any shared package that exports named symbols and has a CJS default via ESM interop (react, react-dom, styled-components, react-router, etc.), import Pkg from 'pkg' through the prebuild shim returned the module namespace object instead of the real default export.

Concretely, when a host prebundles a shared react this way, downstream consumers see Pkg.createElement as undefined because the default they got was { default: React, useState, useEffect, ... } rather than React itself. This tends to surface as Cannot read properties of undefined (reading 'createElement') from prebundled shared React.

Fix

Emit __mfPrebuildNamespace.default ?? __mfPrebuildNamespace in the named-exports branch, matching the other three branches.

Tests

Added a regression test in src/virtualModules/__tests__/virtualShared_preBuild.test.ts that verifies the emitted code for a package with named exports (a) contains export default __mfPrebuildNamespace.default ?? __mfPrebuildNamespace; and (b) does not emit the old export default __mfPrebuildExports; line.

  • pnpm test — 598/598 passing (was 597/597; +1 new test).
  • pnpm fmt.check / pnpm typecheck clean.
  • Verified the new test fails against main without the source fix and passes with it.

The namedExports branch of writePreBuildLibPath emitted `export default __mfPrebuildExports` (the raw namespace object) instead of unwrapping `namespace.default`. All three sibling branches in the same function (react/jsx-runtime, react/jsx-dev-runtime, and the no-namedExports fallback) already emit `namespace.default ?? namespace`, so this was inconsistent codegen.

For any shared package that exports named symbols AND has a CJS default export via ESM interop (React, react-dom, styled-components, react-router when consumed through the shim), `import Pkg from 'pkg'` would return the namespace object instead of the real default. Symptoms include `Cannot read properties of undefined (reading 'createElement')` from prebundled shared React.

Fix: emit `__mfPrebuildNamespace.default ?? __mfPrebuildNamespace`, matching the other three branches.
@pkg-pr-new

pkg-pr-new Bot commented Jul 2, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@module-federation/vite@870

commit: 6a9f9d6

@gioboa gioboa left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests With Different Frameworks

Image

@gioboa gioboa left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @muiradams for your help 🎉

@gioboa gioboa merged commit 1aa1ae4 into module-federation:main Jul 2, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants