Skip to content

refactor(webpack-bundler-runtime): compose the bundler runtime from adapters - #5137

Open
ScriptedAlchemy wants to merge 14 commits into
rfc5128/01-runtime-core-kernelfrom
rfc5128/02-bundler-runtime-compose
Open

ScriptedAlchemy wants to merge 14 commits into
rfc5128/01-runtime-core-kernelfrom
rfc5128/02-bundler-runtime-compose

Conversation

@ScriptedAlchemy

@ScriptedAlchemy ScriptedAlchemy commented Sep 25, 2026 •

Copy link
Copy Markdown
Member

Part of RFC #5128 (alternate proposal to #5036).
Stack: 2 of 7. Base: #5135 (rfc5128/01-runtime-core-kernel). Next: #5139.
Landing order: #5135 → #5137 → #5139 → #5134 → #5140 → #5141 → #5142.
Companions on main: #5143 (disabled remote loadEntry), #5144 (enhanced duplicate serializer keys). #5126 (@rspack/core 2) is on main. PR 6 and 7 include it.

What changes

The webpack bundler runtime can now be composed from parts. Importers of the @module-federation/webpack-bundler-runtime root see the same default-export keys, named exports, and federation.runtime as on main. A generated bootstrap can instead import only the adapters and runtime-core capabilities a build uses, so the parts it leaves out are not in the module graph. Enhanced and rspack generate that bootstrap in #5140 and #5141.

  • @module-federation/webpack-bundler-runtime/compose exports createFederation({ buildId, capabilities, adapters }).
  • Four adapters live at ./adapters/remotes, ./adapters/consumes, ./adapters/share-scope, and ./adapters/container. The tree-shaking share plugin moves into its own module, and the consumes adapter adds it before init.
  • The root export is rebuilt from the same adapters and the capability defines. No module under src except the root imports the @module-federation/runtime root, the runtime-core root, or runtime/helpers. getRemoteEntry and getGlobalSnapshotInfoByModuleInfo now come from runtime-core/kernel.

In a composed build, federation.runtime is a shim with only init. init builds the composed instance with the build id as the default id. Rspack native runtimes before 2.0.0-beta.1 call federation.runtime.init, so the shim needs it. The shim has no loadScriptNode. Node loads through the instance platform instead (#5139), so web builds do not import the Node loader.

Verification

  • The root .d.ts bundled runtime-core types, so a consumer tsc failed with TS2322. The consumer tsc now reports 0 errors.
  • compose.spec.ts checks that each adapter exposes exactly its keys, and that the composer's bundler runtime exposes only S and init. Init runs beforeInit first and passes buildId as the default id. Each adapter runs against an enabled and a disabled handler. For example, consumes without the shared capability fails with the disabled-shared error. federation.runtime has exactly init. An rspack 1.x style key copy followed by federation.runtime.init(initOptions) keeps the build id. The spec copies the keys the way moduleFederationDefaultRuntime.js in @rspack/core 1.7.9 does.
  • legacy-root.spec.ts checks that the root's default-export keys, named exports, and federation.runtime namespace match origin/main. The built dist/index.cjs was also compared by hand against the parent's.
  • import-boundary.spec.ts checks that no source module except index.ts imports the runtime or runtime-core root or runtime/helpers.
  • The webpack-bundler-runtime suite passes 128/128, with tsc and lint clean. Enhanced's configCases pass.
  • Independent verification passed at 9afd2096e. The gates review ran at 785a04d99, and its two audit findings were fixed and reproduced as fixed at the merged head. The runtime.init shim and the removal of loadScriptNode from the shim each passed a delta review. The live head ab1bcc040 has the same patch over its parent.
  • CI passes at ab1bcc040 with 19 checks.
  • This PR does not run rspack. The composed build on @rspack/core 1.5.8, 1.7.9, and 2.1.10 is tested in feat(rspack): redirect the native bundler runtime to a composed entry #5141.

Deviations from the RFC

  • The federation.runtime shim carries init. Rspack native runtimes before 2.0.0-beta.1 copy the federation keys and then call federation.runtime.init, and composed builds crashed on rspack 1.5 to 1.7 without it. The RFC now lists init in the shim.

Overlaps with open PRs

This PR carries none of the spun-out main fixes and no code from other open PRs. The PRs below change files this PR also changes. This PR does not include their changes.

@changeset-bot

changeset-bot Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: ab1bcc0

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 48 packages
Name Type
@module-federation/webpack-bundler-runtime Minor
@module-federation/enhanced Minor
@module-federation/esbuild Patch
@module-federation/nextjs-mf Patch
@module-federation/runtime-tools Minor
@module-federation/modern-js-v3 Minor
@module-federation/modern-js Minor
@module-federation/node Patch
@module-federation/rsbuild-plugin Minor
@module-federation/rspress-plugin Minor
@module-federation/rstest Minor
@module-federation/storybook-addon Patch
shared-tree-shaking-no-server-host Patch
shared-tree-shaking-no-server-provider Patch
@module-federation/rspack Minor
@module-federation/inject-external-runtime-core-plugin Minor
shared-tree-shaking-with-server-host Patch
shared-tree-shaking-with-server-provider Patch
node-dynamic-remote-new-version Patch
node-dynamic-remote Patch
@module-federation/playground Patch
remote5 Patch
remote6 Patch
website-new Patch
@module-federation/devtools Minor
@module-federation/cli Minor
create-module-federation Minor
@module-federation/dts-plugin Minor
@module-federation/error-codes Minor
@module-federation/managers Minor
@module-federation/manifest Minor
@module-federation/metro Minor
@module-federation/metro-plugin-rnc-cli Minor
@module-federation/metro-plugin-rnef Minor
@module-federation/metro-plugin-rock Minor
@module-federation/retry-plugin Minor
@module-federation/runtime-core Minor
@module-federation/runtime Minor
@module-federation/sdk Minor
@module-federation/third-party-dts-extractor Minor
@module-federation/treeshake-frontend Minor
@module-federation/treeshake-server Minor
@module-federation/bridge-react-webpack-plugin Minor
@module-federation/bridge-react Minor
@module-federation/bridge-shared Minor
@module-federation/bridge-vue3 Minor
@module-federation/observability-plugin Patch
@module-federation/utilities Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-25T13:47:21.970053Z 1b3250f PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@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: 1b3250f26b

ℹ️ 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 +59 to +62
const platform = federation.instance?.platform as
| Partial<NodePlatform>
| undefined;
if (!platform?.loadScriptNode) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Store the initialized instance for the loader shim

When the compose entry is embedded by FederationRuntimePlugin.getTemplate, the imported federation properties are copied into a fresh __webpack_require__.federation, and the result of bundlerRuntime.init is assigned only to that fresh object. This closure still reads the original federation.instance, which therefore remains undefined; in Node composed builds, every runtime.loadScriptNode call throws the missing-platform error even when a node or universal platform capability was supplied. Assign the result of composeInit to the captured federation instance inside init, or resolve the instance from the webpack-require-backed object.

Useful? React with 👍 / 👎.

@pkg-pr-new

pkg-pr-new Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

@module-federation/devtools

pnpm add https://pkg.pr.new/@module-federation/devtools@ab1bcc0

@module-federation/cli

pnpm add https://pkg.pr.new/@module-federation/cli@ab1bcc0

create-module-federation

pnpm add https://pkg.pr.new/create-module-federation@ab1bcc0

@module-federation/dts-plugin

pnpm add https://pkg.pr.new/@module-federation/dts-plugin@ab1bcc0

@module-federation/enhanced

pnpm add https://pkg.pr.new/@module-federation/enhanced@ab1bcc0

@module-federation/error-codes

pnpm add https://pkg.pr.new/@module-federation/error-codes@ab1bcc0

@module-federation/esbuild

pnpm add https://pkg.pr.new/@module-federation/esbuild@ab1bcc0

@module-federation/managers

pnpm add https://pkg.pr.new/@module-federation/managers@ab1bcc0

@module-federation/manifest

pnpm add https://pkg.pr.new/@module-federation/manifest@ab1bcc0

@module-federation/metro

pnpm add https://pkg.pr.new/@module-federation/metro@ab1bcc0

@module-federation/metro-plugin-rnc-cli

pnpm add https://pkg.pr.new/@module-federation/metro-plugin-rnc-cli@ab1bcc0

@module-federation/metro-plugin-rnef

pnpm add https://pkg.pr.new/@module-federation/metro-plugin-rnef@ab1bcc0

@module-federation/metro-plugin-rock

pnpm add https://pkg.pr.new/@module-federation/metro-plugin-rock@ab1bcc0

@module-federation/modern-js

pnpm add https://pkg.pr.new/@module-federation/modern-js@ab1bcc0

@module-federation/modern-js-v3

pnpm add https://pkg.pr.new/@module-federation/modern-js-v3@ab1bcc0

@module-federation/native-federation-tests

pnpm add https://pkg.pr.new/@module-federation/native-federation-tests@ab1bcc0

@module-federation/native-federation-typescript

pnpm add https://pkg.pr.new/@module-federation/native-federation-typescript@ab1bcc0

@module-federation/nextjs-mf

pnpm add https://pkg.pr.new/@module-federation/nextjs-mf@ab1bcc0

@module-federation/node

pnpm add https://pkg.pr.new/@module-federation/node@ab1bcc0

@module-federation/observability-plugin

pnpm add https://pkg.pr.new/@module-federation/observability-plugin@ab1bcc0

@module-federation/playground

pnpm add https://pkg.pr.new/@module-federation/playground@ab1bcc0

@module-federation/retry-plugin

pnpm add https://pkg.pr.new/@module-federation/retry-plugin@ab1bcc0

@module-federation/rsbuild-plugin

pnpm add https://pkg.pr.new/@module-federation/rsbuild-plugin@ab1bcc0

@module-federation/rspack

pnpm add https://pkg.pr.new/@module-federation/rspack@ab1bcc0

@module-federation/rspress-plugin

pnpm add https://pkg.pr.new/@module-federation/rspress-plugin@ab1bcc0

@module-federation/rstest

pnpm add https://pkg.pr.new/@module-federation/rstest@ab1bcc0

@module-federation/runtime

pnpm add https://pkg.pr.new/@module-federation/runtime@ab1bcc0

@module-federation/runtime-core

pnpm add https://pkg.pr.new/@module-federation/runtime-core@ab1bcc0

@module-federation/runtime-tools

pnpm add https://pkg.pr.new/@module-federation/runtime-tools@ab1bcc0

@module-federation/sdk

pnpm add https://pkg.pr.new/@module-federation/sdk@ab1bcc0

@module-federation/storybook-addon

pnpm add https://pkg.pr.new/@module-federation/storybook-addon@ab1bcc0

@module-federation/third-party-dts-extractor

pnpm add https://pkg.pr.new/@module-federation/third-party-dts-extractor@ab1bcc0

@module-federation/treeshake-frontend

pnpm add https://pkg.pr.new/@module-federation/treeshake-frontend@ab1bcc0

@module-federation/treeshake-server

pnpm add https://pkg.pr.new/@module-federation/treeshake-server@ab1bcc0

@module-federation/typescript

pnpm add https://pkg.pr.new/@module-federation/typescript@ab1bcc0

@module-federation/utilities

pnpm add https://pkg.pr.new/@module-federation/utilities@ab1bcc0

@module-federation/webpack-bundler-runtime

pnpm add https://pkg.pr.new/@module-federation/webpack-bundler-runtime@ab1bcc0

@module-federation/bridge-react

pnpm add https://pkg.pr.new/@module-federation/bridge-react@ab1bcc0

@module-federation/bridge-react-webpack-plugin

pnpm add https://pkg.pr.new/@module-federation/bridge-react-webpack-plugin@ab1bcc0

@module-federation/bridge-shared

pnpm add https://pkg.pr.new/@module-federation/bridge-shared@ab1bcc0

@module-federation/bridge-vue3

pnpm add https://pkg.pr.new/@module-federation/bridge-vue3@ab1bcc0

@module-federation/inject-external-runtime-core-plugin

pnpm add https://pkg.pr.new/@module-federation/inject-external-runtime-core-plugin@ab1bcc0

commit: ab1bcc0

…sed runtime shim

Its only reader is this repo's node runtime plugin, which loads through
instance.platform.loadScriptNode since PR 3. The shim keeps init because
rspack native runtimes before 2.0.0-beta.1 call federation.runtime.init.

This branch has not been deployed

No deployments
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