Repository navigation
feat(runtime)!: add explicit remote updates and SSR revisions - #5074
Conversation
🦋 Changeset detectedLatest commit: e6ddc59 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 |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
@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: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e6ddc59918
ℹ️ 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".
| updateRemotes(): never { | ||
| throw new Error(REMOTE_DISABLED_MESSAGE); | ||
| } |
There was a problem hiding this comment.
Return a rejected promise when remotes are disabled
When experiments.optimization.disableRemote is enabled, this implementation throws synchronously even though the new public updateRemotes() API is declared to return Promise<void>. Consequently, callers using the documented promise contract—for example, mf.updateRemotes(remotes).catch(...)—cannot handle the failure through the returned promise. Make the disabled path return Promise.reject(...) or make the public wrapper async, as is already done for loadRemote and preloadRemote.
Useful? React with 👍 / 👎.
| // Capture caller-owned values immediately; validate again when the queue runs. | ||
| captured = this.prepareRemotes(remotes, true); | ||
| } catch (error) { |
There was a problem hiding this comment.
Defer state-dependent validation until the queued update runs
When an earlier queued update changes or frees an alias, a later update that reuses that alias is rejected here against the pre-update registrations even though it would be valid when its serialized turn begins. For example, with a aliased as old and b aliased as other, queueing an update that changes a to new followed immediately by one that changes b to old rejects the second call before the first completes. Capture and validate caller-owned field shapes immediately, but perform alias checks that depend on host.options.remotes only inside the queued operation.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e6ddc59918
ℹ️ 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".
| const previous = registered || | ||
| remembered.get(name) || { name }; |
There was a problem hiding this comment.
Resolve retained registrations by canonical identity
When a replacement addressed by an alias fails after removing the registration, remembered is keyed only by that alias. If the recovery message addresses the same remote by its canonical name, this lookup misses and fabricates { name }; the recovery de-duplication then selects that stripped target, losing the original alias, type, entryGlobalName, and other options while marking the application serving again. Index or search retained registrations by both canonical name and alias.
Useful? React with 👍 / 👎.
| updateRemotes(): never { | ||
| throw new Error(REMOTE_DISABLED_MESSAGE); |
There was a problem hiding this comment.
Return a rejected promise when remotes are disabled
With experiments.optimization.disableRemote, this implementation throws synchronously even though the public updateRemotes signature promises Promise<void> and the enabled implementation converts validation failures into rejected promises. Code using updateRemotes(...).catch(...) therefore cannot handle this configuration and may crash its callback before a promise exists; return Promise.reject(...) or make the public wrapper async.
Useful? React with 👍 / 👎.
| const update = instance.updateRemotes; | ||
| host.updateRemotes = function (...args: Parameters<typeof update>) { |
There was a problem hiding this comment.
Include updateRemotes in the static-consumption scan
This adds updateRemotes as another out-of-owner mutation that invalidates Modern's static SSR proof, but SSRDependencyPlugin.ts:50 still scans application source only for loadRemote, registerRemotes, importRemote, and eval. An entry containing the new API can consequently be classified as statically safe until that path executes, unlike the equivalent legacy registration call, allowing the adapter to choose selective invalidation despite a known dynamic mutation path. Add updateRemotes to that conservative source scan.
Useful? React with 👍 / 👎.
Description
Replace forced remote registration with
await updateRemotes(remotes). Identical registration is a no-op; conflicting registration andforce: truenow throw. Batch updates validate before cleanup, serialize per instance, retain unspecified remotes, and refresh all live bundler mappings.The Modern SSR owner adds batch publication and application-wide integer revisions. Pending/successful duplicate messages reuse their result; stale or conflicting revisions reject. Applied revisions advance only after publication. Failed mutations remain unavailable, and explicit whole-application recovery includes retained targets from previous failed batches. Results and errors expose operation metadata. Existing selective-entry proofs, shared identity retention and same-process rebuilding remain in place.
Migrates affected examples and runtime API docs. This is a breaking API migration with major changesets; the fixed release group expands the release plan to 3.0.0. Private example/site packages intentionally have no release entries.
Validation: 20 build tasks; runtime-core 147, runtime 94, bundler 128 and Modern 35 tests; strict native artifacts 23; Node E2E 1, runtime browser E2E 26, Modern SSR cache E2E 2. Real Modern HTTP artifacts pass ordinary, numeric/minified and concatenated variants, plus production MF (1) and HTTP (3) tests. Full Prettier, whitespace, commitlint and Changesets parsing/scope checks pass. Existing non-fatal Modern publint and nested-remote DTS warnings remain.
Exact commands and skipped matrices are in
tools/ssr-cache/VALIDATION.md. Worktree validation uses Turbo/package scripts. Unrelated package/framework/builder matrices and sustained load/heap/hydration acceptance remain R6; this PR does not claim final production sign-off. No package publication or deployment.Related Issue
R5 of the MF/Modern SSR cache RFC, following #5072. Target:
feat/mf-ssr-clear-cache.Types of changes
The API migration itself is breaking, as explained above and in the changeset.
Checklist