Skip to content

feat: support MF SSR remote cache clearing - #14368

Draft
2heal1 wants to merge 19 commits into
mainfrom
feat/mf-ssr-clear-cache
Draft

2heal1 wants to merge 19 commits into
mainfrom
feat/mf-ssr-clear-cache

Conversation

@2heal1

@2heal1 2heal1 commented Jun 11, 2026 •

Copy link
Copy Markdown
Member

Summary

Add Module Federation cache clearing for Node SSR. After a remote is updated, the MF runtime can invalidate the remote and the host modules whose cached exports would otherwise keep serving the old remote, without restarting the SSR process.

This PR requires the matching @module-federation/runtime-tools pre-release because that package owns the public clearCache / forced remote registration flow.

Implementation

Compile-time dependency metadata

RemoteRuntimeModule now emits reverse dependency metadata alongside the existing remote-loading data:

  • remoteKeyToRemoteModuleIds: remote key -> remote module IDs.
  • remoteKeyToExternalModuleIds: remote key -> external/container-entry module IDs.
  • remoteModuleIdToConsumerModuleIds: remote module -> direct host consumers.
  • consumerModuleIdToParentModuleIds: consumer -> its direct importers.
  • remoteKeyToChunkIds: remote key -> chunks that load it.

The metadata is generated from the compilation ModuleGraph and ChunkGraph, rather than from HMR state:

  1. For each RemoteModule, obtain its remote_key, module ID, and external dependency module ID.
  2. Read the remote module's incoming connections. Each connection's original_module_identifier is a direct consumer.
  3. For every direct consumer, read its incoming connections to obtain parents/importers.
  4. Include every referenced chunk, so async consumers and their remote chunks are represented.
  5. Sort and deduplicate every generated ID list for stable runtime metadata.

Using the normal module graph means this works in production SSR builds where HMR's module.parents is unavailable.

Runtime invalidation

The runtime-tools cache-clear flow uses those indexes to identify the smallest invalidation set:

  1. Resolve the requested remote to its remote key.
  2. Invalidate its remote and external module state.
  3. Find direct consumers from remoteModuleIdToConsumerModuleIds.
  4. Walk consumerModuleIdToParentModuleIds upward, invalidating cached host-module exports so a later SSR request re-executes the consumer chain and reloads the remote.
  5. Leave module factories intact for local consumers; only remove their executed module-cache entries.

This is necessary because clearing only the remote module is insufficient: a previously executed page/route module can remain in __webpack_require__.c and return old exports without touching the remote loading path.

Node chunk safety

Node require and readFileVm chunk runtimes expose controlled chunkCacheControls:

  • target-specific clear/snapshot/restore operations for installedChunks;
  • CommonJS require.cache cleanup for affected filesystem chunks;
  • per-chunk generations.

A clear invalidates the target chunk generation before clearing it. An older async chunk load checks that generation before installing factories or marking the chunk loaded, so it cannot repopulate the cache after a newer request has begun.

Provider-side cleanup

Container entries expose __webpack_clear_cache__, which clears the provider bundle's module cache. This ensures a reloaded remote does not reuse its own cached exposed-module exports.

Behavior and limits

  • Existing in-flight SSR requests are allowed to complete.
  • The operation invalidates old state; it does not preload or validate the replacement remote.
  • Shared instances are retained by default to avoid splitting process-wide singletons.
  • For native ESM remotes, callers should use versioned entry URLs because Node cannot reliably evict a same-URL ESM module from its native cache.

Tests

  • Runtime metadata covers remote, external module, consumer, parent, and async chunk mappings.
  • SSR cache clearing covers multiple exposes and consumer routes.
  • Covers force-registering a replacement remote entry.
  • Covers pending/rejected remote get, stale async chunk completion, repeated clearing, CommonJS cache cleanup, large payload release, and shared-module retention.
  • Verified locally with:
    • pnpm run build:cli:dev:wasm
    • pnpm run test -t "serialCases/container/mf-ssr-clear-cache"
    • pnpm run lint:js

@github-actions

github-actions Bot commented Jun 12, 2026 •

Copy link
Copy Markdown
Contributor

📦 Binary Size-limit

Comparing 8e63776 to chore: release version 2.2.3 (#15538) by Cong-Cong Pan

❌ Size increased by 28.00KB from 68.58MB to 68.61MB (⬆️0.04%)

@codspeed

codspeed Bot commented Jun 12, 2026 •

Copy link
Copy Markdown
Contributor

Merging this PR will improve performance by 2.18%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 1 improved benchmark
✅ 49 untouched benchmarks
⏩ 47 skipped benchmarks1

Performance Changes

Benchmark BASE HEAD Efficiency
⚡ rust@create_named_chunk_ids 2.9 ms 2.9 ms +2.18%

Tip

Curious why performance improved? Comment @codspeedbot explain why performance improved on this PR, or directly use the CodSpeed MCP with your agent.


Comparing feat/mf-ssr-clear-cache (8e63776) with main (59e2544)

Open in CodSpeed

Footnotes

  1. 47 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

@2heal1 2heal1 changed the title docs: add MF SSR clear cache design feat: support MF SSR remote cache clearing Jun 17, 2026
@2heal1
2heal1 force-pushed the feat/mf-ssr-clear-cache branch from b342f63 to 241134f Compare June 17, 2026 03:25
@github-actions

github-actions Bot commented Jun 17, 2026 •

Copy link
Copy Markdown
Contributor

Rsdoctor Bundle Diff Analysis

Found 5 projects in monorepo, 0 projects with changes.

📊 Quick Summary
Project Total Size Gzip Size Change Gzip Change
react-10k 5.3 MB 1.3 MB 0 0
popular-libs 1.7 MB 523.6 KB 0 0
react-5k 2.6 MB 662.0 KB 0 0
react-1k 799.1 KB 217.5 KB 0 0
ui-components 4.9 MB 1.4 MB 0 0

Generated by Rsdoctor GitHub Action

@2heal1
2heal1 force-pushed the feat/mf-ssr-clear-cache branch from dbf6a50 to cb6bd31 Compare June 17, 2026 06:51
@2heal1
2heal1 force-pushed the feat/mf-ssr-clear-cache branch from 3b1a219 to 1f63da4 Compare June 23, 2026 03:41
@2heal1

2heal1 commented Jun 23, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 99709aee70

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +106 to +110
for (consumer_module_identifier, consumer_module_id) in &consumer_modules {
add_to_mapping(
&mut consumer_module_id_to_parent_module_ids,
consumer_module_id.clone(),
get_parent_module_ids(compilation, module_graph, consumer_module_identifier),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Populate parent metadata transitively

When a remote is consumed through more than one synchronous local layer, this only records parents for the direct remote consumers returned by get_consumer_modules. For a chain like entry -> route -> page -> remoteA, the metadata can expose page -> route but never route -> entry, so a clear-cache walk cannot invalidate the already-executed upper module and subsequent SSR can keep serving closures that still reference the old remote exports.

Useful? React with 👍 / 👎.

@2heal1
2heal1 force-pushed the feat/mf-ssr-clear-cache branch from 99709ae to e65fa31 Compare September 8, 2026 08:13
@2heal1
2heal1 deployed to npm-canary September 11, 2026 03:29 — with GitHub Actions Active
@2heal1
2heal1 deployed to npm-canary September 11, 2026 10:31 — with GitHub Actions Active
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

Deploying rspack with  Cloudflare Pages  Cloudflare Pages

Latest commit: ba52386
Status: ✅  Deploy successful!
Preview URL: https://907fb725.rspack-v2.pages.dev
Branch Preview URL: https://feat-mf-ssr-clear-cache.rspack-v2.pages.dev

View logs

@2heal1
2heal1 deployed to npm-canary September 16, 2026 13:26 — with GitHub Actions Active

This branch was successfully deployed

1 active deployment
npm-canary — ba52386c Deployed Sep 16, 2026 by 2heal1 via Release Canary #8384
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.

1 participant