Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
36c7e8f
feat(enhanced)!: compose the federation runtime bootstrap by default
ScriptedAlchemy Sep 25, 2026
bd074d9
test(enhanced): assert the composed plan for disableRemote and disabl…
ScriptedAlchemy Sep 25, 2026
d01ec17
feat(node)!: load remote entries only through the instance platform
ScriptedAlchemy Sep 25, 2026
fe83d46
feat(webpack-bundler-runtime,enhanced)!: remove federation.runtime
ScriptedAlchemy Sep 25, 2026
187dfdd
feat(runtime-core,runtime,webpack-bundler-runtime)!: stop reading the…
ScriptedAlchemy Sep 25, 2026
22c1db4
feat(enhanced,rspack)!: stop emitting the capability and build-id def…
ScriptedAlchemy Sep 25, 2026
60e40ab
feat(managers,enhanced)!: fail the build when the runtime family is t…
ScriptedAlchemy Sep 25, 2026
5cdbb5f
Merge remote-tracking branch 'origin/rfc5128/06-rspack-composed' into…
ScriptedAlchemy Sep 25, 2026
b7a13a4
feat(rspack)!: compose the federation runtime by default
ScriptedAlchemy Sep 25, 2026
ca1e839
feat(enhanced,rspack,sdk)!: remove experiments.composedRuntime
ScriptedAlchemy Sep 25, 2026
940685d
docs: replace the removed runtime defines with runtime/compose
ScriptedAlchemy Sep 25, 2026
cc8cf9a
refactor(managers,enhanced,rspack): let selectMode mark a requested f…
ScriptedAlchemy Sep 25, 2026
7b46e85
fix(runtime-core): keep an empty default instance id
ScriptedAlchemy Sep 25, 2026
7849bfc
Merge remote-tracking branch 'origin/rfc5128/06-rspack-composed' into…
ScriptedAlchemy Sep 25, 2026
8bdf981
fix(runtime-core): register the share scope under the id from options
ScriptedAlchemy Sep 25, 2026
f1fe068
test(enhanced): let the older-family build emit so the test can read …
ScriptedAlchemy Sep 25, 2026
52ce340
fix(rspack): plan the consumes adapter for async startup
ScriptedAlchemy Sep 25, 2026
00109f5
fix(rstest): keep the aliased bundler runtime bundled
ScriptedAlchemy Sep 25, 2026
dd2a305
chore: list managers and rstest in the major changeset
ScriptedAlchemy Sep 25, 2026
34ecd25
Merge remote-tracking branch 'origin/rfc5128/06-rspack-composed' into…
ScriptedAlchemy Sep 25, 2026
eb706c8
Merge remote-tracking branch 'origin/rfc5128/06-rspack-composed' into…
ScriptedAlchemy Sep 25, 2026
9c782c3
Merge remote-tracking branch 'origin/rfc5128/06-rspack-composed' into…
ScriptedAlchemy Sep 25, 2026
5ac49cb
feat(rspack)!: remove resolveRspackRuntimeAlias
ScriptedAlchemy Sep 25, 2026
2840f62
fix(runtime-core): register the share scope once the options are final
ScriptedAlchemy Sep 25, 2026
453999c
fix(enhanced): pass the build id to the full-runtime bootstrap
ScriptedAlchemy Sep 25, 2026
21e2f48
fix(rspack): pass the build id to the native runtime
ScriptedAlchemy Sep 25, 2026
3052ce6
fix(managers): say what an older runtime family lacks
ScriptedAlchemy Sep 25, 2026
295d730
test(rspack): cover the build error for an older runtime family
ScriptedAlchemy Sep 25, 2026
b0a6c25
test(enhanced): assert the consumes path stays out of builds without …
ScriptedAlchemy Sep 25, 2026
001e19c
chore: name the removed runtime export in the major changeset
ScriptedAlchemy Sep 25, 2026
4989a4a
docs: describe capabilities and the build id instead of the removed d…
ScriptedAlchemy Sep 25, 2026
0e7bc2b
feat(rspack)!: require @rspack/core 1.5 or newer
ScriptedAlchemy Sep 25, 2026
571ef30
chore: describe the full-runtime fallback in the major changeset
ScriptedAlchemy Sep 25, 2026
cf40a35
fix(rspack): pass the build id through a data: runtime plugin
ScriptedAlchemy Sep 25, 2026
6fff0f9
fix(rstest): keep data: runtime plugins bundled
ScriptedAlchemy Sep 25, 2026
a5cf4b0
feat(rspack)!: require @rspack/core 2.0.0-beta.1 or newer
ScriptedAlchemy Sep 25, 2026
8f40ea8
fix(webpack-bundler-runtime): keep federation.runtime.init on the ful…
ScriptedAlchemy Sep 25, 2026
9805677
fix(rspack): accept @rspack/core 1.5 again
ScriptedAlchemy Sep 25, 2026
76bd8b7
Merge remote-tracking branch 'origin/rfc5128/06-rspack-composed' into…
ScriptedAlchemy Sep 25, 2026
df9aa3a
chore: quote the older runtime family error in the major changeset
ScriptedAlchemy Sep 25, 2026
b27e763
Merge remote-tracking branch 'origin/rfc5128/06-rspack-composed' into…
ScriptedAlchemy Sep 25, 2026
953ceeb
Merge remote-tracking branch 'origin/rfc5128/06-rspack-composed' into…
ScriptedAlchemy Sep 25, 2026
1f51217
chore: name the runtime family errors in the major changeset
ScriptedAlchemy Sep 25, 2026
f6d2e8b
fix(node): name a missing federation instance in the script loader
ScriptedAlchemy Sep 25, 2026
729099e
Merge remote-tracking branch 'origin/rfc5128/06-rspack-composed' into…
ScriptedAlchemy Sep 25, 2026
9f596f0
test(runtime): compose the optimized-runtime scenarios instead of rea…
ScriptedAlchemy Sep 25, 2026
9861d70
Revert "test(runtime): compose the optimized-runtime scenarios instea…
ScriptedAlchemy Sep 25, 2026
db5159f
Merge remote-tracking branch 'origin/rfc5128/06-rspack-composed' into…
ScriptedAlchemy Sep 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .changeset/composed-runtime-default-major.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
'@module-federation/runtime-core': major
'@module-federation/runtime': major
'@module-federation/webpack-bundler-runtime': major
'@module-federation/enhanced': major
'@module-federation/rspack': major
'@module-federation/sdk': major
'@module-federation/node': major
'@module-federation/managers': major
---

The composed federation runtime is the default. `ModuleFederationPlugin` generates a bootstrap that imports only the runtime parts the build uses, and `experiments.composedRuntime` is removed. A build that cannot compose gets the define-free full-runtime bootstrap: an external runtime (`experiments.externalRuntime`, `provideExternalRuntime`), a runtime package in `externals` or in a user `resolve.alias`, or rspack without `experiments.VirtualModulesPlugin`. It warns, except for the two external-runtime experiments, which ask for the full runtime.

Removed:

- The `FEDERATION_OPTIMIZE_NO_SHARED`, `FEDERATION_OPTIMIZE_NO_REMOTE`, `FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN`, `FEDERATION_HAS_EXPOSES`, and `FEDERATION_BUILD_IDENTIFIER` defines. The plugins no longer emit them and the runtime no longer reads them. Use `experiments.optimization.disable*` with the plugin, or import the capabilities you need from `@module-federation/runtime/compose` when you bundle the runtime yourself.
- The `@module-federation/runtime` namespace on `__webpack_require__.federation.runtime`, `federation.runtime.loadScriptNode`, and the named `runtime` export of `@module-federation/webpack-bundler-runtime` (so also of `@module-federation/runtime-tools/webpack-bundler-runtime`). `federation.runtime` keeps only `init`, because the native runtime of `@rspack/core` before 2.0.0-beta.1 calls `federation.runtime.init`. Use `__webpack_require__.federation.instance`, `instance.platform.loadScriptNode` for the Node loader, or import `@module-federation/runtime` directly.
- The fallback in `@module-federation/node` to `federation.runtime.loadScriptNode`.
- `resolveRspackRuntimeAlias` from `@module-federation/rspack/plugin`. The wrapper no longer aliases `@module-federation/runtime$`, so the helper has no use.

`@module-federation/rspack` now needs `@rspack/core` 1.5 or newer, the first release with `experiments.VirtualModulesPlugin`. The wrapper still falls back to the full runtime, with a warning, when the plugin is missing.

The build now fails when the runtime packages it resolves cannot compose. It fails when a runtime package cannot be resolved (`<package> could not be resolved from <dir>`), when the resolved package has another name (`<package> at <root> is named "<name>"`), or when an older release lacks the subpath exports: `<package> at <root> does not export "<subpath>": the installed runtime family lacks the subpath exports this build needs; update the @module-federation runtime packages to the release that added them (2.10.0)`. 2.10.0 is the release that adds the subpath exports. `ENV_TARGET`, `FEDERATION_ALLOW_NEW_FUNCTION`, and `FEDERATION_DEBUG` are unchanged.
2 changes: 1 addition & 1 deletion apps/website-new/docs/en/configure/experiments.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ This object contains flags related to build-time optimizations that can affect t
- Required: No
- Default: `false`

When set to `true`, this option defines the `FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN` global constant as `true` during the build. In the `@module-federation/runtime-core`, this prevents the `snapshotPlugin()` and `generatePreloadAssetsPlugin()` from being included and initialized within the Module Federation instance.
When set to `true`, the federation bootstrap that the plugin generates does not import the snapshot capability of `@module-federation/runtime-core`. The `snapshotPlugin()` and `generatePreloadAssetsPlugin()` are then not in the build and are not initialized within the Module Federation instance.

**Impact:**

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,48 +56,26 @@ For Webpack, change the import to `@module-federation/enhanced/webpack`.

This combination is suitable for a minimal producer that only exposes modules, does not consume other Remotes, does not use shared dependencies, and does not depend on Manifest / Snapshot data. Start from the defaults and enable only options that are safe for your build.

### Configure a runtime-only project with environment variables
### Compose the runtime in a project without ModuleFederationPlugin

If your project bundles `@module-federation/runtime` or `@module-federation/runtime-core` directly without `ModuleFederationPlugin`, use environment variables and replace them with build-time booleans in your bundler configuration.
If your project bundles the runtime directly without `ModuleFederationPlugin`, import only the capabilities it uses from `@module-federation/runtime/compose`. A capability that you do not import is not in the module graph, in any optimization mode.

For example, a project that does not consume Remotes, use shared dependencies or Snapshot data, and has no `exposes` can build with:
For example, a web host that only consumes Remotes:

```bash
FEDERATION_OPTIMIZE_NO_REMOTE=true \
FEDERATION_OPTIMIZE_NO_SHARED=true \
FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN=true \
FEDERATION_HAS_EXPOSES=false \
pnpm build
```

Webpack must replace the values explicitly:

```ts title="webpack.config.ts"
import webpack from 'webpack';

const federationDefines = {
FEDERATION_OPTIMIZE_NO_REMOTE: JSON.stringify(
process.env.FEDERATION_OPTIMIZE_NO_REMOTE === 'true',
),
FEDERATION_OPTIMIZE_NO_SHARED: JSON.stringify(
process.env.FEDERATION_OPTIMIZE_NO_SHARED === 'true',
),
FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN: JSON.stringify(
process.env.FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN === 'true',
),
FEDERATION_HAS_EXPOSES: JSON.stringify(
process.env.FEDERATION_HAS_EXPOSES !== 'false',
),
};
```ts
import { init } from '@module-federation/runtime/compose';
import { remote } from '@module-federation/runtime-core/remote';
import { web } from '@module-federation/runtime-core/platform/web';

export default {
plugins: [new webpack.DefinePlugin(federationDefines)],
};
const host = init({ name: 'host', remotes }, { remote, platform: web });
await host.loadRemote('shop/Button');
```

With Rspack, pass the same `federationDefines` object to `rspack.DefinePlugin`. With Vite, pass it to the top-level `define` option.
Add `shared` from `@module-federation/runtime-core/shared` and `snapshot` from `@module-federation/runtime-core/snapshot` when the build needs them. `import { init } from '@module-federation/runtime'` still gives the full runtime.

Leaving environment variables as runtime strings is not enough. The bundler must replace them with `true` or `false` at build time so the minifier can remove the corresponding code. All capabilities remain enabled when no value is provided, preserving existing behavior.
:::info
The `FEDERATION_OPTIMIZE_NO_REMOTE`, `FEDERATION_OPTIMIZE_NO_SHARED`, `FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN`, and `FEDERATION_HAS_EXPOSES` defines were removed. The runtime no longer reads them.
:::

## What each option removes

Expand Down
2 changes: 1 addition & 1 deletion apps/website-new/docs/pt-BR/configure/experiments.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Este objeto contains flags related para build-time optimizations esse pode affec
- Obrigatório: No
- Padrão: `false`

Quando definir para `true`, este opção defines o `FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN` global constant as `true` during o build. No `@module-federation/runtime-core`, este prevents o `snapshotPlugin()` e `generatePreloadAssetsPlugin()` de being included e initialized within o Module Federation instance.
Quando definida como `true`, o bootstrap de federation gerado pelo plugin não importa a capacidade de snapshot do `@module-federation/runtime-core`. Assim, `snapshotPlugin()` e `generatePreloadAssetsPlugin()` não entram no build e não são inicializados na instância do Module Federation.

**Impact:**

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,48 +56,26 @@ Para Webpack, altere o import para `@module-federation/enhanced/webpack`.

Essa combinação é adequada para um produtor mínimo que apenas expõe módulos, não consome outros Remotes, não usa dependências compartilhadas e não depende de Manifest / Snapshot. Comece com os valores padrão e habilite somente opções que sejam seguras para o seu build.

### Configurar um projeto que usa apenas o runtime com variáveis de ambiente
### Compor o runtime em um projeto sem ModuleFederationPlugin

Se o projeto empacota `@module-federation/runtime` ou `@module-federation/runtime-core` diretamente, sem `ModuleFederationPlugin`, use variáveis de ambiente e substitua-as por valores booleanos durante o build na configuração do bundler.
Se o seu projeto empacota o runtime diretamente, sem `ModuleFederationPlugin`, importe de `@module-federation/runtime/compose` apenas as capacidades que ele usa. Uma capacidade que você não importa não entra no grafo de módulos, em nenhum modo de otimização.

Por exemplo, um projeto que não consome Remotes, não usa dependências compartilhadas nem Snapshot e não tem `exposes` pode usar:
Por exemplo, um host web que apenas consome Remotes:

```bash
FEDERATION_OPTIMIZE_NO_REMOTE=true \
FEDERATION_OPTIMIZE_NO_SHARED=true \
FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN=true \
FEDERATION_HAS_EXPOSES=false \
pnpm build
```

No Webpack, os valores devem ser substituídos explicitamente:

```ts title="webpack.config.ts"
import webpack from 'webpack';

const federationDefines = {
FEDERATION_OPTIMIZE_NO_REMOTE: JSON.stringify(
process.env.FEDERATION_OPTIMIZE_NO_REMOTE === 'true',
),
FEDERATION_OPTIMIZE_NO_SHARED: JSON.stringify(
process.env.FEDERATION_OPTIMIZE_NO_SHARED === 'true',
),
FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN: JSON.stringify(
process.env.FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN === 'true',
),
FEDERATION_HAS_EXPOSES: JSON.stringify(
process.env.FEDERATION_HAS_EXPOSES !== 'false',
),
};
```ts
import { init } from '@module-federation/runtime/compose';
import { remote } from '@module-federation/runtime-core/remote';
import { web } from '@module-federation/runtime-core/platform/web';

export default {
plugins: [new webpack.DefinePlugin(federationDefines)],
};
const host = init({ name: 'host', remotes }, { remote, platform: web });
await host.loadRemote('shop/Button');
```

No Rspack, passe o mesmo objeto `federationDefines` para `rspack.DefinePlugin`. No Vite, passe-o para a opção `define` no nível principal.
Adicione `shared` de `@module-federation/runtime-core/shared` e `snapshot` de `@module-federation/runtime-core/snapshot` quando o build precisar deles. `import { init } from '@module-federation/runtime'` continua fornecendo o runtime completo.

Não basta deixar as variáveis de ambiente como strings no código executado. O bundler deve substituí-las por `true` ou `false` durante o build para que o minificador remova o código correspondente. Quando nenhum valor é fornecido, todos os recursos continuam habilitados, preservando o comportamento existente.
:::info
Os defines `FEDERATION_OPTIMIZE_NO_REMOTE`, `FEDERATION_OPTIMIZE_NO_SHARED`, `FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN` e `FEDERATION_HAS_EXPOSES` foram removidos. O runtime não os lê mais.
:::

## O que cada opção remove

Expand Down
2 changes: 1 addition & 1 deletion apps/website-new/docs/zh/configure/experiments.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
- 是否必填:否
- 默认值:`false`

当设置为 `true` 时,该选项会在构建期间将全局常量 `FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN` 定义为 `true`。在 `@module-federation/runtime-core` 中,这会阻止 `snapshotPlugin()` 与 `generatePreloadAssetsPlugin()` 被打包并在 Module Federation 实例中初始化。
当设置为 `true` 时,插件生成的 federation 启动代码不会导入 `@module-federation/runtime-core` 的 snapshot 能力,因此 `snapshotPlugin()` 与 `generatePreloadAssetsPlugin()` 不会被打包,也不会在 Module Federation 实例中初始化。

**影响:**

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,48 +56,26 @@ export default {

上面的组合适用于一个非常精简的纯生产者:它只对外提供模块,不消费其他 Remote、不使用共享依赖,也不依赖 Manifest / Snapshot。实际项目应从默认值开始,只打开已经确认安全的选项。

### 纯 Runtime 项目通过环境变量配置
### 不使用 ModuleFederationPlugin 时按需组合 Runtime

如果项目直接打包 `@module-federation/runtime` 或 `@module-federation/runtime-core`,没有使用上面的 `ModuleFederationPlugin`,可以用环境变量控制构建,并在打包配置中把环境变量替换为编译期布尔值。
如果项目不使用 `ModuleFederationPlugin`,而是直接打包 Runtime,请从 `@module-federation/runtime/compose` 只导入项目用到的能力。没有导入的能力不会进入模块图,与优化模式无关。

例如,一个不消费 Remote、不使用共享依赖和 Snapshot,也不包含 `exposes` 的项目可以这样构建:
例如,一个只消费 Remote 的 Web Host:

```bash
FEDERATION_OPTIMIZE_NO_REMOTE=true \
FEDERATION_OPTIMIZE_NO_SHARED=true \
FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN=true \
FEDERATION_HAS_EXPOSES=false \
pnpm build
```

Webpack 配置需要显式完成替换:

```ts title="webpack.config.ts"
import webpack from 'webpack';

const federationDefines = {
FEDERATION_OPTIMIZE_NO_REMOTE: JSON.stringify(
process.env.FEDERATION_OPTIMIZE_NO_REMOTE === 'true',
),
FEDERATION_OPTIMIZE_NO_SHARED: JSON.stringify(
process.env.FEDERATION_OPTIMIZE_NO_SHARED === 'true',
),
FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN: JSON.stringify(
process.env.FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN === 'true',
),
FEDERATION_HAS_EXPOSES: JSON.stringify(
process.env.FEDERATION_HAS_EXPOSES !== 'false',
),
};
```ts
import { init } from '@module-federation/runtime/compose';
import { remote } from '@module-federation/runtime-core/remote';
import { web } from '@module-federation/runtime-core/platform/web';

export default {
plugins: [new webpack.DefinePlugin(federationDefines)],
};
const host = init({ name: 'host', remotes }, { remote, platform: web });
await host.loadRemote('shop/Button');
```

Rspack 使用 `rspack.DefinePlugin` 传入同一份 `federationDefines`。Vite 可以把它传给顶层 `define` 配置。
构建需要时,再从 `@module-federation/runtime-core/shared` 导入 `shared`,从 `@module-federation/runtime-core/snapshot` 导入 `snapshot`。`import { init } from '@module-federation/runtime'` 仍然提供完整的 Runtime。

环境变量不能直接作为字符串留在运行时代码中,必须在构建时替换成 `true` 或 `false`,压缩工具才能删除对应代码。没有显式配置时,上述能力都会保持开启,兼容现有行为。
:::info
`FEDERATION_OPTIMIZE_NO_REMOTE`、`FEDERATION_OPTIMIZE_NO_SHARED`、`FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN` 和 `FEDERATION_HAS_EXPOSES` 已被移除,Runtime 不再读取它们。
:::

## 每个开关会移除什么

Expand Down
3 changes: 1 addition & 2 deletions arch-doc/architecture-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,6 @@ sequenceDiagram
```typescript
// Pattern for any bundler
interface BundlerRuntimeBridge {
runtime: typeof coreRuntime; // Core runtime reference
instance?: ModuleFederation; // Runtime instance
bundlerRuntime: { // Bundler-specific implementations
remotes: (options) => Promise<Module>;
Expand Down Expand Up @@ -726,7 +725,7 @@ graph TB

subgraph "Snapshot Handler"
SnapshotHandler[SnapshotHandler]
OptCheck["Optimization Check<br/>FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN"]
OptCheck["Snapshot Capability<br/>runtime-core/snapshot"]
ManifestGen["Manifest Generation<br/>generateSnapshotFromManifest"]
end

Expand Down
3 changes: 1 addition & 2 deletions arch-doc/implementation-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -657,13 +657,12 @@ export class FederationRuntimeModule extends RuntimeModule {
return Template.asString([
`// Federation Runtime Module`,
`var ${federationGlobal} = ${federationGlobal} || {};`,
`${federationGlobal}.runtime = __bundler_require__("${RUNTIME_PATH}");`,
`${federationGlobal}.initOptions = ${JSON.stringify(this.initOptions)};`,

// Initialize federation runtime
`if (!${federationGlobal}.instance) {`,
Template.indent([
`${federationGlobal}.instance = ${federationGlobal}.runtime.init(${federationGlobal}.initOptions);`
`${federationGlobal}.instance = __bundler_require__("${RUNTIME_PATH}").init(${federationGlobal}.initOptions);`
]),
`}`,

Expand Down
Loading
Loading