Skip to content

feat(managers): resolve runtime families atomically - #5093

Open
ScriptedAlchemy wants to merge 14 commits into
mainfrom
rfc5036/01-runtime-family-resolver
Open

ScriptedAlchemy wants to merge 14 commits into
mainfrom
rfc5036/01-runtime-family-resolver

Conversation

@ScriptedAlchemy

@ScriptedAlchemy ScriptedAlchemy commented Sep 18, 2026 •

Copy link
Copy Markdown
Member

Part of RFC #5036. An alternate proposal is open at #5128 with its own stack. This PR stays open until the decision on #5036 is made.
Stack: 1 of 7. Base: main. Next: #5094.
Landing order: #5093 → #5094 → #5095 → #5096 → #5097 → #5098 → #5107.

What changes

The resolver changes nothing for users yet, because nothing calls it. Maintainers get a @module-federation/managers/runtime-selection subpath that checks one runtime family as a whole before compiler plugins select capabilities. The old per-package lookup can mix copies when a custom implementation is incomplete.

The resolver walks each family dependency from the package that requested it and records each member's real root. It rejects bad metadata, missing entries, unreachable roles, late participants, and a federation plugin applied directly to a child compiler. That last case used to be dropped silently.

A package without family metadata stays on the old path. There, two copies of a member at the same version count as one, because npm nesting produces that layout today. Copies at different versions are rejected. A package that opts into conditions must declare its layout, allowed requests, selectors, facade, and entry loader.

Capability reduction matches main for a single plugin. remotes with disableRemote: true, or shared with disableShared: true, sets the disable define and is not a conflict. Only participants that disagree raise capability-conflict. An unknown experiments.optimization.target is ignored, as on main.

The branch also carries two fixes that change output today. Runtime-chunk hoisting skips connections webpack has pruned (#5116). CommonJS declarations are emitted as .d.cts, and the require types condition in seven packages points at them (#5124). The file list also shows the ResourceLoadContext import fix, which is already on main as #5114.

Verification

  • The branch history was rewritten on 2026-09-26 to remove attribution trailers from commit messages only. Every tree and patch is identical to the verified head; 00b53e387 is the rewritten tip.

  • The managers build, 43 managers tests, managers lint, and Prettier pass.

  • The carried fixes bring their own tests. A config case that fails on main keeps a pruned import out of the runtime chunk. A node:test case checks one declaration path per format. tools/scripts/check-dts.mjs parses every built declaration at the end of build:packages.

  • CI at 00b53e387 passed all 26 checks, including every end-to-end suite.

  • No build calls the resolver here, so only the managers unit tests exercise it. feat(enhanced): coordinate runtime family selection #5094 wires it into Enhanced and Rspack.

Deviations from the RFC

None noted.

Overlaps with open PRs

File overlaps with 6 other open PRs

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

@changeset-bot

changeset-bot Bot commented Sep 18, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 00b53e3

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/runtime Minor
@module-federation/runtime-core Minor
@module-federation/runtime-tools Minor
@module-federation/webpack-bundler-runtime Minor
@module-federation/sdk Minor
@module-federation/error-codes Minor
@module-federation/enhanced Minor
@module-federation/managers Minor
@module-federation/devtools Minor
@module-federation/dts-plugin Minor
@module-federation/esbuild Patch
@module-federation/metro Minor
@module-federation/modern-js-v3 Minor
@module-federation/modern-js Minor
@module-federation/nextjs-mf Patch
@module-federation/node Patch
@module-federation/observability-plugin Patch
@module-federation/playground Patch
@module-federation/retry-plugin Minor
@module-federation/bridge-react Minor
@module-federation/bridge-vue3 Minor
website-new Patch
@module-federation/rspack Minor
@module-federation/inject-external-runtime-core-plugin Minor
@module-federation/cli Minor
@module-federation/manifest Minor
@module-federation/rsbuild-plugin Minor
@module-federation/rspress-plugin Minor
@module-federation/rstest Minor
@module-federation/storybook-addon Patch
@module-federation/utilities Patch
@module-federation/bridge-react-webpack-plugin Minor
shared-tree-shaking-no-server-host Patch
shared-tree-shaking-no-server-provider Patch
@module-federation/metro-plugin-rnc-cli Minor
@module-federation/metro-plugin-rnef Minor
@module-federation/metro-plugin-rock 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
remote5 Patch
remote6 Patch
create-module-federation Minor
@module-federation/third-party-dts-extractor Minor
@module-federation/treeshake-frontend Minor
@module-federation/treeshake-server Minor
@module-federation/bridge-shared Minor

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

@pkg-pr-new

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

Copy link
Copy Markdown

Open in StackBlitz

@module-federation/devtools

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

@module-federation/cli

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

create-module-federation

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

@module-federation/dts-plugin

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

@module-federation/enhanced

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

@module-federation/error-codes

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

@module-federation/esbuild

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

@module-federation/managers

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

@module-federation/manifest

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

@module-federation/metro

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

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

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

@module-federation/metro-plugin-rnef

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

@module-federation/metro-plugin-rock

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

@module-federation/modern-js

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

@module-federation/modern-js-v3

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

@module-federation/native-federation-tests

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

@module-federation/native-federation-typescript

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

@module-federation/nextjs-mf

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

@module-federation/node

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

@module-federation/observability-plugin

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

@module-federation/playground

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

@module-federation/retry-plugin

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

@module-federation/rsbuild-plugin

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

@module-federation/rspack

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

@module-federation/rspress-plugin

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

@module-federation/rstest

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

@module-federation/runtime

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

@module-federation/runtime-core

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

@module-federation/runtime-tools

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

@module-federation/sdk

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

@module-federation/storybook-addon

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

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

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

@module-federation/treeshake-frontend

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

@module-federation/treeshake-server

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

@module-federation/typescript

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

@module-federation/utilities

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

@module-federation/webpack-bundler-runtime

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

@module-federation/bridge-react

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

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

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

@module-federation/bridge-shared

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

@module-federation/bridge-vue3

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

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

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

commit: 00b53e3

@github-actions

github-actions Bot commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

Bundle Size Report

14 package(s) changed, 29 unchanged.

Package dist + ESM entry

Package Total dist (raw) Delta ESM gzip Delta
@module-federation/enhanced 818.0 kB +62 B (+0.0%) 672 B no change
@module-federation/error-codes 27.0 kB +12 B (+0.0%) 210 B no change
@module-federation/inject-external-runtime-core-plugin 5.7 kB +567 B (+10.7%) 519 B no change
@module-federation/managers 154.5 kB +83.8 kB (+118.4%) 243 B no change
@module-federation/runtime 24.4 kB +4.0 kB (+19.6%) 724 B no change
@module-federation/runtime-core 354.2 kB +43.7 kB (+14.1%) 570 B no change
@module-federation/runtime-tools 8.4 kB +698 B (+8.8%) 142 B no change
@module-federation/sdk 177.6 kB +48.7 kB (+37.8%) 785 B no change
@module-federation/webpack-bundler-runtime 147.6 kB +79.5 kB (+116.8%) 531 B no change

Bundle targets

Package Web bundle (gzip) Delta Node bundle (gzip) Delta
@module-federation/cli 2.3 kB -4 B (-0.2%) 2.4 kB -32 B (-1.3%)
@module-federation/core 1.0 kB -5 B (-0.5%) 1.0 kB -33 B (-3.0%)
@module-federation/devtools 30.3 kB no change 30.3 kB -24 B (-0.1%)
@module-federation/enhanced 2.7 kB +2 B (+0.1%) 2.8 kB -43 B (-1.5%)
@module-federation/metro-plugin-rnc-cli 416 B no change 435 B -26 B (-5.6%)
@module-federation/node 9.1 kB +2 B (+0.0%) 9.1 kB -27 B (-0.3%)

Consumer scenarios

Scenario Web output (gzip) Delta Node output (gzip) Delta Gap (node-web) Delta
Enhanced remoteEntry 22.2 kB -109 B (-0.5%) 23.7 kB -110 B (-0.5%) +1.6 kB -1 B

Total dist (raw): 23.66 MB (+260.9 kB (+1.1%))
Total ESM gzip: 111.7 kB (no change)
Total web bundle (gzip): 253.3 kB (-5 B (-0.0%))
Total node bundle (gzip): 255.5 kB (-185 B (-0.1%))
Tracked ./bundler entry gzip: 563 B (no change)
Tracked ./bundler web bundle (gzip): 4.9 kB (no change)
Tracked ./bundler node bundle (gzip): 4.9 kB (no change)

Bundle sizes are generated with rslib (Rspack). Package-root metrics preserve the historical report. Tracked subpath exports such as ./bundler are measured separately so ENV_TARGET-driven tree-shaking is visible. Bare imports are externalized to keep package-level sizes consistent, and assets are emitted as resources.

@ScriptedAlchemy
ScriptedAlchemy force-pushed the rfc5036/01-runtime-family-resolver branch from 85929d0 to 335ca42 Compare September 18, 2026 15:26
Resolve each family edge from its issuer.

Reject split roots, malformed metadata, and missing members.

Export parser and selection state from runtime-selection. Keep package conditions inactive.
@ScriptedAlchemy
ScriptedAlchemy force-pushed the rfc5036/01-runtime-family-resolver branch from 335ca42 to d52545d Compare September 18, 2026 15:33
One plugin with `remotes` and `disableRemote: true` (or `shared` and
`disableShared: true`) used to throw `capability-conflict`. On main the
disable flag wins and sets the matching FEDERATION_OPTIMIZE_* define.
Restore that: within one participant the explicit disable flag wins.
Different participants that disagree still throw.
npm nesting can install the same runtime package at the same version
under two parents. In legacy-defines mode that build works on main, so
the resolver now treats members with the same name and version as one
member. Condition-mode families keep strict root identity.
`experiments.optimization.target` with a null or unrecognized value
used to throw `invalid-target`. Main ignores such values and sets no
ENV_TARGET define. Fall back to compiler target inference instead.
A `split-family` error from the compiler slot now names both requested
implementations and their resolved roots. A `dependsOn` that is present
but not an array is a malformed contract instead of an empty list. A role
that no `dependsOn` edge reaches from runtime-tools is a malformed
topology, not a missing member. The slot test builds its own fixture
instead of resolving the workspace runtime-tools package.
Remove `resolverVisibleRoots` (nothing reads it), the `hasExposes` and
`isPresentRecord` duplicates of `hasConfiguredRecord` and `isRecord`, a
no-op spread of the parsed selectors, and the unused `sdkDir` parameter
of the test fixture helper.
Inheriting the parent selection used to overwrite the child's own
participants, so a plugin applied to a child compiler was dropped
without an error.
The remote handler's loadEntry hook typed `resourceContext` as
`ResourceLoadContext` without importing it. The emitted
`dist/remote/index.d.ts` then referenced an undeclared name, so consumers
with `skipLibCheck: false` got TS2304.
Add a config case where a runtime plugin imports an unused export of a
sideEffects: false package. The runtime chunk must not contain that
module while a used package stays in it. Fails on main.
getAllReferencedModules followed every outgoing connection, so modules
webpack had pruned were forced back into the runtime chunk. Skip a
connection whose active state is false in every runtime.
Add a node:test case for createDualFormatConfig's outExtensions mapper
that calls it with rolldown's format names ('es' and 'cjs') and expects
distinct declaration paths per format. It fails on the current helper,
which only matches 'esm'.

Add tools/scripts/check-dts.mjs, run at the end of build:packages. It
parses every packages/*/dist declaration file with the TypeScript
compiler and fails on syntax diagnostics, so a torn .d.ts fails in the
package that emitted it instead of in a downstream build.
tsdown calls outExtensions with rolldown's format name, 'es', while
createModernOutExtensions matched 'esm'. The ESM pass therefore got no
mapping and fell back to dist/<entry>.d.ts, the same path the CJS
mapping named. Both passes run at once and their writes interleaved,
which left packages/runtime/dist/core.d.ts torn on a CI runner.

The mapper now matches 'es' and gives each declaration the extension of
its JavaScript sibling: .js gets .d.ts, .cjs gets .d.cts, .mjs gets
.d.mts. The sdk config no longer bypasses the mapper, since tsdown's
own default also wrote one .d.ts for both passes in a type: module
package. The require types condition in runtime, runtime-core,
runtime-tools, webpack-bundler-runtime, sdk, error-codes, and
assemble-release-plan now points at the .d.cts file, which also clears
the publint warning about ESM-typed declarations under require.
@github-actions

github-actions Bot commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Deploying with ☁️ Zephyr Cloud

The latest preview deployments for this pull request.

Status Name Latest Commit Version URL Updated (UTC)
✅ Deployment successful!
View deployment
website-new 00b53e3 Version ↗ 26 Sept 2026, 05:01

Affected deployment targets

Application Type Target
website-new Environment latest ↗
website-new Tag latest ↗
website-new Tag web_rfc5036-01-runtime-family-resolver_nestor_lopez ↗

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant