Conversation
🦋 Changeset detectedLatest commit: 5978eed The changes in this PR will be included in the next version bump. This PR includes changesets to release 48 packages
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 |
@module-federation/devtools
@module-federation/cli
create-module-federation
@module-federation/dts-plugin
@module-federation/enhanced
@module-federation/error-codes
@module-federation/esbuild
@module-federation/managers
@module-federation/manifest
@module-federation/metro
@module-federation/metro-plugin-rnc-cli
@module-federation/metro-plugin-rnef
@module-federation/metro-plugin-rock
@module-federation/modern-js
@module-federation/modern-js-v3
@module-federation/native-federation-tests
@module-federation/native-federation-typescript
@module-federation/nextjs-mf
@module-federation/node
@module-federation/observability-plugin
@module-federation/playground
@module-federation/retry-plugin
@module-federation/rsbuild-plugin
@module-federation/rspack
@module-federation/rspress-plugin
@module-federation/rstest
@module-federation/runtime
@module-federation/runtime-core
@module-federation/runtime-tools
@module-federation/sdk
@module-federation/storybook-addon
@module-federation/third-party-dts-extractor
@module-federation/treeshake-frontend
@module-federation/treeshake-server
@module-federation/typescript
@module-federation/utilities
@module-federation/webpack-bundler-runtime
@module-federation/bridge-react
@module-federation/bridge-react-webpack-plugin
@module-federation/bridge-shared
@module-federation/bridge-vue3
@module-federation/inject-external-runtime-core-plugin
commit: |
Bundle Size Report11 package(s) changed, 32 unchanged. Package dist + ESM entry
Bundle targets
Tree-shakable entrypoints
Consumer scenarios
Total dist (raw): 23.40 MB (-1000 B (-0.0%)) Bundle sizes are generated with rslib (Rspack). Package-root metrics preserve the historical report. Tracked subpath exports such as |
|
🤖 Constructing the local class fixes new instances. I reproduced this at PR head // disabledRuntime: disableRemote=true, build ID app@1.0.0
// fullRuntime: disableRemote=false, build ID app@2.0.0
const remote = { name: 'tiny', entry: localHttpRemoteEntry };
const disabled = disabledRuntime.init({ name: 'app', version: '1.0.0', remotes: [remote] });
const full = fullRuntime.init({ name: 'app', version: '1.0.0', remotes: [remote] });
await full.loadRemote('tiny/value'); // actual: throws remote-disabled error
await fullRuntime.loadRemote('tiny/value'); // actual: throws the same error
// Expected for an isolated full runtime: { value: 'remote-value' } from both.The full runtime's The same cases fail with the original parent runtime source at Could you either check capabilities when 🤖 Addressed for updated runtimes in 4b1858e7e. The global instance lookup now requires the same remote, shared, and snapshot capabilities before it checks build ID or name and version. Both initialization orders and matching build IDs now work, and compatible instances are still reused with their shared state. The nine real-bundle tests pass, and the two package suites pass 227 tests with none skipped. 869e211b9 adds the build target to the capabilities. A web-target build loads entries with the DOM loader, so a Node runtime must not reuse its instance. At that head the focused suite has eleven cases, and the two package suites pass 229 tests. Run the focused tests with: pnpm --filter @module-federation/runtime exec rstest run --include '**/__tests__/optimized-runtimes.spec.ts'Mixing old and new runtimes still has limits. I used the previous PR head Matching capabilities also don't guarantee that two runtime package versions are compatible. In the reproduction above, |
…icitly Each scenario now builds its own bundles with named options instead of deriving build ids and flags from the scenario name. Adds two collisions the capability check has to catch: a web-target runtime reused by a Node runtime, and a remote-capable runtime without snapshot plugins.
A web-target build loads remote entries with the DOM loader and ships a loadScriptNode stub, so a Node runtime that reused its instance could not load remotes. The capability check now includes the build target, and the capabilities are a readable string stored on each instance, so a runtime that composes its capabilities per instance can describe itself.
… capabilities Each instance records runtimeCapabilities in the format main uses (#5145): remote, shared, snapshot, and the platform target. Public init and runtime/compose init skip page-global instances whose string differs from the caller's, and public createInstance constructs its own ModuleFederation class instead of __DEBUG_CONSTRUCTOR__.
Description
Two bundles that each ship their own copy of
@module-federation/runtimecan share one page. When they were built with different optimizations, one could end up running on the other's runtime instance and lose features it was built with. Two paths caused this:createInstanceconstructed the class stored in__FEDERATION__.__DEBUG_CONSTRUCTOR__. In debug mode, the last bundle to load sets that global, so a full host could get an instance built withdisableRemote.createInstancenow constructs its own importedModuleFederation. The global is still set, and code that wants it can construct it directly.initreused the first global instance with a matching build id, or a matching name and version, without checking what that instance could do. It now reuses an instance only when its capabilities match the caller's: remote loading, shared loading, snapshot plugins, and the build target. The build target matters because a web-target build loads entries with the DOM loader and ships aloadScriptNodestub, so a Node runtime reusing its instance cannot load remotes.The capabilities are a string on each instance, for example
remote,shared,snapshot,web. Other bundles read it from the instance rather than from its constructor, so a runtime that composes its capabilities per instance can describe itself.Compatibility
__DEBUG_CONSTRUCTOR__to replace the classcreateInstancebuilds must now construct that class itself.Tests
packages/runtime/__tests__/optimized-runtimes.spec.tsbuilds independent runtime bundles from source with their own flags, serves a real HTTP container and manifest, and runs each scenario in a fresh process. The eleven cases cover:init;createInstancestaying fresh;Each capability has a case that fails without it. The target case failed before the capability string included it, with
document is not defined.Commands, on Node 24:
pnpm --filter @module-federation/runtime-core exec rstest run --include '**/__tests__/*.spec.ts'passes 126 tests.pnpm --filter @module-federation/runtime exec rstest run --include '**/__tests__/*.spec.ts'passes 103 tests, including the 11 above.pnpm --filter @module-federation/runtime-core --filter @module-federation/runtime run lintpasses.tscon both packages reports only the twoutils/preload.tserrors thatmainalready has.Browser and e2e jobs were not run locally.
Related
The composed-runtime stack for RFC #5128 changes the same lookup (#5135 moves it into
runtime/src/instance.ts). There, a composed instance's capabilities come from what its bundle passes in, so the stack needs to set this per-instance string from those capabilities. That follow-up is tracked on the stack.Types of changes
Checklist