feat(core): add Module Federation compatibility mode#1407
feat(core): add Module Federation compatibility mode#1407ScriptedAlchemy wants to merge 41 commits into
Conversation
Update the federation example pins to the latest pkg.pr.new canary published from module-federation/core#4320, and backfill the missing tarball integrity hashes in the lockfile so frozen installs pass with pnpm >= 11.4.
Deploying rstest with
|
| Latest commit: |
11b1872
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://bea0ade3.rstest.pages.dev |
| Branch Preview URL: | https://feat-federation-v2.rstest.pages.dev |
pkg.pr.new preview
|
Rsdoctor Bundle Diff AnalysisFound 13 projects in monorepo, 4 projects with changes. 📊 Quick Summary
📋 Detailed Reports (Click to expand)📁 browserPath:
📦 Download Diff Report: browser Bundle Diff 📁 browser-uiPath:
📦 Download Diff Report: browser-ui Bundle Diff 📁 core/browserPath:
📦 Download Diff Report: core/browser Bundle Diff 📁 core/mainPath:
📦 Download Diff Report: core/main Bundle Diff Generated by Rsdoctor GitHub Action |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 40086e4ff7
ℹ️ 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".
- drop the stale `__rstest_dynamic_import__` global when a reused worker (`isolate: false`) runs a non-federation file after a federation one - wrap a pre-existing `__webpack_require__.f` with the same chunk-handler guard proxy so the Module Federation node runtime cannot overwrite `readFileVm` / `require` in that runtime-module ordering - remove the dead local `__rstest_dynamic_import__` binding flagged by code scanning: the runtime module is IIFE-isolated, so only the global is observable
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 510f431fba
ℹ️ 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".
State that federation: true requires the unreleased @rstest/core federation build (web-infra-dev/rstest#1407, pkg.pr.new canary), declare the rstest:federation plugin name a stable public contract, and reword the provenance blurb: the package is rstest federation mode's companion plugin, not an extraction from @rstest/core.
Install the pkg.pr.new canaries from web-infra-dev/rstest#1407 (commit 40086e4) for @rstest/core, browser, browser-react, and the rsbuild/rslib adapters so the demos' federation: true flag exercises real rstest federation support instead of being a silent no-op on 0.8.x. Bump @rsbuild/core and @rsbuild/plugin-react to the 2.x line the canary uses and document the required pairing in the demo configs.
…back Raw absolute specifiers (`C:\...`) reach native `import()` when federated async-node chunks call the global fallback; convert them through `pathToFileURL` like `resolveDynamicImport.ts` does so Windows drive letters are not parsed as URL schemes.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bedbf1a056
ℹ️ 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".
The hook closure binds `import()` to the vm dynamic-import context of the bundle that installed it, so a worker reused with `isolate: false` must not carry the previous file's hook into the next federation-enabled file. Drop it unconditionally in `preparePool`; `mockRuntimeCode.js` reinstalls a fresh one bound to the current bundle.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 773bf1f044
ℹ️ 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".
pkg.pr.new preview
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 309d3b9b59
ℹ️ 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".
RFC: Module Federation Compatibility ModeThis PR adds an opt-in Module Federation compatibility mode for Rstest's Related work:
SummaryFederated tests have two runtimes sharing responsibility for module loading:
Without a compatibility layer, Module Federation's Node runtime can evaluate The contract in this PR is intentionally small:
Why this needs a first-class modeRstest rewrites and bundles test modules so APIs such as In ordinary test bundles, dynamic imports are routed through Rstest's injected Module Federation changes the graph shape:
So a single test can cross from "Rstest-controlled code" into Runtime modelflowchart LR
A["Rstest config: federation: true"] --> B["Worker/global setup sets globalThis.__rstest_federation__"]
B --> C["mockRuntimeCode installs federation shims"]
C --> D["Rstest mock/runtime ownership remains active"]
E["@module-federation/rstest"] --> F["ModuleFederationPlugin plus Rstest-safe defaults"]
F --> G["Remote entries and chunks load in Node-compatible form"]
D --> H["Federated test executes inside the Rstest worker"]
G --> H
Runtime requirements1. Opt-in behavior
import { defineConfig } from '@rstest/core';
export default defineConfig({
federation: true,
});or through the CLI for one-off runs: rstest run --federationThis keeps existing Node, jsdom, happy-dom, and browser-mode behavior unchanged. 2. The runtime flag must be set before user codeThe worker sets
The runtime module gates its shims on that flag, so setting it late would make 3. Dynamic import fallback must preserve import originsFederated The fallback must:
This keeps federation chunk loading aligned with the same origin-aware dynamic 4. Worker reuse must not leak stale hooksWith That prevents a federation file from leaving a stale fallback behind for later 5. Federation chunk handlers must not bypass RstestModule Federation can install placeholder chunk handlers such as Compatibility mode no-ops only the known throwing placeholders and allows the It also protects Rstest-owned chunk-loading handlers. If the Module Federation 6. Dynamic external imports must still respect mocksDynamic This matters for federated code because remote containers and runtime plugins Build-side splitThe companion
This keeps Rstest from becoming a Module Federation configuration surface. Rstest For standalone application or remote prebuilds, examples should use the normal Example shapeimport { federation } from '@module-federation/rstest';
import { defineConfig } from '@rstest/core';
export default defineConfig({
federation: true,
plugins: [
federation({
name: 'main_app',
remotes: {
'component-app': 'component_app@http://localhost:3001/remoteEntry.js',
},
shared: {
react: { singleton: true },
},
}),
],
});Non-goals
Validation in this PRThe PR includes coverage for the compatibility contract:
Reviewer checklist
|
|
commonjs e2e test failed ⬇️ ❌ FAIL federation/index.test.ts > federation > should install federation runtime shims when enabled in config (retry x2) Rstest v0.10.6 Repro command: https://github.com/web-infra-dev/rstest/actions/runs/28143939302/job/83347403961 |
# Conflicts: # pnpm-lock.yaml
|
@9aoy fixed, thanks for the repro. Root cause: in the CommonJS / The fix adds a worker-global current-origin hook ( Verified with the exact repro: cd e2e && RSTEST_OUTPUT_MODULE=false pnpm exec rstest 'federation/index.test.ts' --testNamePattern 'federation > should install federation runtime shims when enabled in config'Also rechecked the latest PR head ( |
Resolve lockfile conflict and align Rstest federation runtime with async-node chunk loading.
Preserve remote federation fixes and regenerated lockfile after branch moved upstream.
# Conflicts: # pnpm-lock.yaml
pkg.pr.new preview
|
# Conflicts: # pnpm-lock.yaml
# Conflicts: # pnpm-lock.yaml
|
@ScriptedAlchemy hey, the |
Summary
Rstest's Node test runtime overrides
import()and webpack chunk handlers for mocking, which breaks tests that load Module Federation remotes. This PR adds an opt-in federation compatibility mode so federated apps can be tested in Node:federation: booleanconfig option and--federationCLI flag.mockRuntimeCode.js, gated onglobalThis.__rstest_federation__: a placeholder chunk-handler bootstrap, an__rstest_dynamic_import__fallback for non-mocked specifiers, and a__webpack_require__.fProxy guard so federation's chunk loaders coexist with the mock runtime.examples/federation), 8 unit tests, an e2e suite with 3 fixtures, and bilingual docs.This mode pairs with the
@module-federation/rstestRsbuild plugin (module-federation/core#4320); the examples pin its latest pkg.pr.new canary (1b77b1a). Browser mode is unaffected. Supersedes #842.Validation: lint, typecheck, build, unit tests, e2e, and federation examples all pass locally (webkit e2e skipped: missing system deps).
Related Links
Checklist