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

Skip to content

feat(ssr): support mf-manifest.json as remote entry URL#798

Merged
gioboa merged 28 commits into
module-federation:mainfrom
tonoizer:feat/ssr-manifest-support
Jun 16, 2026
Merged

feat(ssr): support mf-manifest.json as remote entry URL#798
gioboa merged 28 commits into
module-federation:mainfrom
tonoizer:feat/ssr-manifest-support

Conversation

@tonoizer

@tonoizer tonoizer commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary

SSR hosts can use entry: "…/mf-manifest.json" interchangeably with remoteEntry.js. On the server, ssrEntryLoader reads metaData.ssrRemoteEntry from the manifest and loads the Node SSR entry. This unlocks Module Federation Chrome DevTools manifest-based discovery.

Scope (intentionally narrow):

  • ssrEntryLoader — manifest-first SSR resolution for .json entries; HEAD-check ssrRemoteEntry; fallback to __mf_server__ / URL convention; existing remoteEntry.js path unchanged
  • index.tsconfigEnvironment sets ENV_TARGET: "node" on server/ssr Vite environments only (client stays "web")

Out of scope: no changes to virtual remote wrappers, shared prebuild codegen, or client-side manifest handling (handled by @module-federation/enhanced runtime).

Usage

Remote (manifest: true required):

federation({ name: "remote", filename: "remoteEntry.js", manifest: true, exposes: {} });

Host (either entry style):

remotes: {
  remote: {
    type: "module",
    name: "remote",
    entry: "http://localhost:4174/mf-manifest.json", // or …/remoteEntry.js
  },
},

Test plan

  • pnpm test (ssrEntryLoader manifest-as-entry + ENV_TARGET configEnvironment tests)
  • pnpm playwright test --project=multi-example (10/10)

Enable manifest-first SSR entry resolution, ENV_TARGET node for
Environment API server builds, and synchronous remote/shared exports
on first server render so hosts can use mf-manifest.json interchangeably
with remoteEntry.js.

Co-authored-by: Cursor <[email protected]>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@tonoizer

Copy link
Copy Markdown
Contributor Author

I can also adjust the vite examples PR (gioboa/module-federation-vite-examples#6) to use the manifest instead of the remoteEntry.js as a demo.

@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 for your help

Comment thread MANIFEST_SSR.md Outdated
@pkg-pr-new

pkg-pr-new Bot commented Jun 10, 2026

Copy link
Copy Markdown

Open in StackBlitz

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

commit: 25249c4

@gioboa gioboa changed the title feat(ssr): support mf-manifest.json as remote entry URL feat(ssr): support mf-manifest.json as remote entry URL Jun 10, 2026
tonoizer and others added 3 commits June 10, 2026 20:55
Vite 5/6 may invoke config() without a bound `this`, so read SSR target
only from config.build.ssr there. Environment API ssr/server targets stay
in configEnvironment, with the unit test updated accordingly.

Co-authored-by: Cursor <[email protected]>
Use lazy client initPromise in browser builds while SSR bundles await
the local fallback, so singleton shared libs initialize once in preview
and named workspace exports stay defined on the server.

Co-authored-by: Cursor <[email protected]>
@tonoizer tonoizer requested a review from gioboa June 10, 2026 19:53
tonoizer and others added 12 commits June 11, 2026 08:29
Use existing __mfRemotePending.then chains instead of await in generated
remote modules so unified/client wrappers stay synchronous for Nuxt and
other frameworks. Workspace singleton shares keep initPromise.then lazy
fallbacks in build output without import.meta.env.SSR await branches.

Co-authored-by: Cursor <[email protected]>
configEnvironment was mutating a shared define object, so the ssr env's
node target leaked into the client graph and pulled Node builtins into
the browser. Copy define per environment so client stays web and ssr
stays node.

Co-authored-by: Cursor <[email protected]>
Revert virtualRemoteEntry, virtualShared_preBuild, and their tests to
main. Remove the merged react-redux optimizeDeps test from index.test.ts
so the branch diff stays focused on manifest-as-entry SSR support.

Co-authored-by: Cursor <[email protected]>
configEnvironment now returns early for client environments so ENV_TARGET
stays web in the browser graph. SSR entry resolution is cached per remote
entry URL so mixed remoteEntry.js and mf-manifest.json hosts resolve
correctly.

Co-authored-by: Cursor <[email protected]>
Use sync local share imports during SSR builds while keeping lazy
initPromise on the client so workspace singletons initialize once in
preview without breaking named exports on the server.

Co-authored-by: Cursor <[email protected]>
…nner

Fall through to the HTTP temp-file loader when ModuleRunner is unavailable
or returns an invalid module, and probe /__mf_ssr__/ and /__mf_server__ when
a pre-resolved .ssr.js URL from the manifest is unreachable.

Co-authored-by: Cursor <[email protected]>
Comment thread src/index.ts

@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.

I did a check with LLM and there are few things to fix.
Findings:

  1. src/index.ts:627 removes LOAD_SHARE_TAG / PREBUILD_TAG from parse-end exclusion. That reverts the recent “reduce latency” behavior and
    makes generated shared modules gate parsePromise again. Risk: large builds wait/timeout on MF-generated virtual modules unrelated to app
    parse completion.
  2. src/utils/ssrEntryLoader.ts:550 now falls through from /mf_ssr/ ModuleRunner failure/unavailable into fetchEsmToTempFile. For dev SSR
    this path is known broken: served SSR entry imports virtual:mf-exposes-ssr:*, and temp-file import can’t resolve Vite virtual ids. This
    silently masks runner failures and does wasted/brittle fetch/import work.
  3. src/index.ts:1105 configEnvironment overwrites existing env-level define.ENV_TARGET. Root config() deliberately preserves user-defined
    ENV_TARGET; this hook should likely do same or warn.

@tonoizer tonoizer requested a review from gioboa June 13, 2026 14:23
Comment thread src/virtualModules/virtualRemoteEntry.ts Outdated
Comment thread src/virtualModules/virtualShared_preBuild.ts
@tonoizer tonoizer requested a review from gioboa June 14, 2026 15:44
Resolved conflict in virtualShared_preBuild.test.ts by preserving the
SSR-specific assertions (if (import.meta.env.SSR) guard and await import)
from the PR while incorporating the initPromise.then assertion from
upstream. Dropped upstream's not.toContain('await ') assertion which is
incompatible with the SSR branch that intentionally uses await.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Comment thread src/virtualModules/virtualShared_preBuild.ts Outdated
Comment thread src/virtualModules/virtualShared_preBuild.ts
@tonoizer tonoizer requested a review from gioboa June 15, 2026 21:14

@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 @tonoizer
I manually tested it with the Nuxt example and SSR manifest is working fine.

@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 merged commit e173aba into module-federation:main Jun 16, 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