Skip to content

Commit 730a705

Browse files
refactor(examples): move topology changes below runtime registration
1 parent f144233 commit 730a705

File tree

13 files changed

+148
-120
lines changed

13 files changed

+148
-120
lines changed

examples/rsbuild-rsc-federation-remote/rsbuild.config.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { pluginReact } from '@rsbuild/plugin-react';
44
import { rspack } from '@rspack/core';
55
import { Layers, pluginRSC } from 'rsbuild-plugin-rsc';
66

7-
const containerName = 'rsbuild_container';
7+
const containerName = 'rsbuild_remote';
88
type EnvironmentName = 'server' | 'client';
99

1010
const unifiedExposes = {
@@ -108,10 +108,6 @@ export default defineConfig({
108108
rspack: (config, { target }) => {
109109
const isServerBuild = target === 'node';
110110
const environment: EnvironmentName = isServerBuild ? 'server' : 'client';
111-
const remotes = {
112-
remote: 'remote',
113-
};
114-
115111
if (isServerBuild) {
116112
config.target = 'async-node';
117113
}
@@ -126,10 +122,6 @@ export default defineConfig({
126122
: { type: 'var', name: containerName },
127123
manifest: isServerBuild ? true : { fileName: 'mf-manifest.client' },
128124
exposes: resolveExposes(environment),
129-
remotes,
130-
runtimePlugins: isServerBuild
131-
? ['@module-federation/node/runtimePlugin']
132-
: [],
133125
experiments: {
134126
asyncStartup: true,
135127
},

examples/rsbuild-rsc-federation-remote/scripts/verify-manifest.mjs

Lines changed: 50 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,21 @@ invariant(
8080

8181
const clientStats = readJSON(clientStatsPath);
8282
const clientManifest = readJSON(clientManifestPath);
83+
const containerName = 'rsbuild_remote';
84+
const sharedPackageName = 'rsbuild-rsc-federation-shared';
85+
const sharedActionsPackageName = 'rsbuild-rsc-federation-shared/server-actions';
8386

84-
const sharedStats = stats.shared.find((item) => item.name === 'rsc-shared-key');
85-
invariant(sharedStats, 'Expected shared entry for "rsc-shared-key" in stats');
87+
const sharedStats = stats.shared.find(
88+
(item) => item.name === sharedPackageName,
89+
);
90+
invariant(
91+
sharedStats,
92+
`Expected shared entry for "${sharedPackageName}" in stats`,
93+
);
94+
invariant(
95+
sharedStats.shareKey === 'rsc-shared-key',
96+
`Expected shared shareKey "rsc-shared-key", got "${sharedStats.shareKey}"`,
97+
);
8698
invariant(sharedStats.rsc, 'Expected rsc metadata on shared stats entry');
8799
invariant(
88100
sharedStats.rsc.lookup === 'rsc-shared-key',
@@ -110,11 +122,15 @@ invariant(
110122
);
111123

112124
const sharedActionsStats = stats.shared.find(
113-
(item) => item.name === 'rsc-shared-actions-key',
125+
(item) => item.name === sharedActionsPackageName,
114126
);
115127
invariant(
116128
sharedActionsStats,
117-
'Expected shared entry for "rsc-shared-actions-key" in stats',
129+
`Expected shared entry for "${sharedActionsPackageName}" in stats`,
130+
);
131+
invariant(
132+
sharedActionsStats.shareKey === 'rsc-shared-actions-key',
133+
`Expected shared actions shareKey "rsc-shared-actions-key", got "${sharedActionsStats.shareKey}"`,
118134
);
119135
invariant(
120136
sharedActionsStats.rsc,
@@ -134,8 +150,8 @@ const exposeStats = stats.exposes.find((item) => item.path === './button');
134150
invariant(exposeStats, 'Expected expose entry "./button" in stats');
135151
invariant(exposeStats.rsc, 'Expected rsc metadata on expose stats entry');
136152
invariant(
137-
exposeStats.rsc.lookup === 'rsbuild_container/button',
138-
`Expected expose lookup "rsbuild_container/button", got "${exposeStats.rsc.lookup}"`,
153+
exposeStats.rsc.lookup === `${containerName}/button`,
154+
`Expected expose lookup "${containerName}/button", got "${exposeStats.rsc.lookup}"`,
139155
);
140156
invariant(
141157
exposeStats.rsc.clientReferences.includes('default'),
@@ -155,8 +171,8 @@ invariant(
155171
'Expected rsc metadata on expose "./consumer"',
156172
);
157173
invariant(
158-
consumerExposeStats.rsc.lookup === 'rsbuild_container/consumer',
159-
`Expected expose lookup "rsbuild_container/consumer", got "${consumerExposeStats.rsc.lookup}"`,
174+
consumerExposeStats.rsc.lookup === `${containerName}/consumer`,
175+
`Expected expose lookup "${containerName}/consumer", got "${consumerExposeStats.rsc.lookup}"`,
160176
);
161177
invariant(
162178
Array.isArray(consumerExposeStats.rsc.serverActions) &&
@@ -173,8 +189,8 @@ invariant(
173189
'Expected rsc metadata on expose "./composed"',
174190
);
175191
invariant(
176-
composedExposeStats.rsc.lookup === 'rsbuild_container/composed',
177-
`Expected expose lookup "rsbuild_container/composed", got "${composedExposeStats.rsc.lookup}"`,
192+
composedExposeStats.rsc.lookup === `${containerName}/composed`,
193+
`Expected expose lookup "${containerName}/composed", got "${composedExposeStats.rsc.lookup}"`,
178194
);
179195
invariant(
180196
composedExposeStats.rsc.clientReferences.includes('default'),
@@ -193,41 +209,44 @@ invariant(
193209
'Expected rsc metadata on expose "./server-mixed"',
194210
);
195211
invariant(
196-
serverMixedExposeStats.rsc.lookup === 'rsbuild_container/server-mixed',
197-
`Expected expose lookup "rsbuild_container/server-mixed", got "${serverMixedExposeStats.rsc.lookup}"`,
212+
serverMixedExposeStats.rsc.lookup === `${containerName}/server-mixed`,
213+
`Expected expose lookup "${containerName}/server-mixed", got "${serverMixedExposeStats.rsc.lookup}"`,
198214
);
199215
invariant(
200216
Array.isArray(serverMixedExposeStats.rsc.serverActions) &&
201217
serverMixedExposeStats.rsc.serverActions.length > 0,
202218
'Expected expose "./server-mixed" serverActions to be non-empty',
203219
);
204220

205-
const remoteStats = stats.remotes.find(
206-
(item) => item.alias === 'remote' && item.moduleName === 'Button',
207-
);
208-
invariant(remoteStats, 'Expected remote/Button consumption entry in stats');
209-
invariant(remoteStats.rsc, 'Expected rsc metadata on remote stats entry');
210221
invariant(
211-
remoteStats.rsc.lookup === 'remote/Button',
212-
`Expected remote lookup "remote/Button", got "${remoteStats.rsc.lookup}"`,
222+
Array.isArray(stats.remotes) && stats.remotes.length === 0,
223+
`Expected provider stats remotes to be empty, got ${stats.remotes.length}`,
213224
);
214225

215226
const manifestShared = manifest.shared.find(
216-
(item) => item.name === 'rsc-shared-key',
227+
(item) => item.name === sharedPackageName,
217228
);
218229
invariant(manifestShared?.rsc, 'Expected shared rsc metadata in manifest');
230+
invariant(
231+
manifestShared.shareKey === 'rsc-shared-key',
232+
'Manifest shared shareKey mismatch',
233+
);
219234
invariant(
220235
manifestShared.rsc.lookup === 'rsc-shared-key',
221236
'Manifest shared lookup mismatch',
222237
);
223238

224239
const manifestSharedActions = manifest.shared.find(
225-
(item) => item.name === 'rsc-shared-actions-key',
240+
(item) => item.name === sharedActionsPackageName,
226241
);
227242
invariant(
228243
manifestSharedActions?.rsc,
229244
'Expected shared actions rsc metadata in manifest',
230245
);
246+
invariant(
247+
manifestSharedActions.shareKey === 'rsc-shared-actions-key',
248+
'Manifest shared actions shareKey mismatch',
249+
);
231250
invariant(
232251
manifestSharedActions.rsc.lookup === 'rsc-shared-actions-key',
233252
'Manifest shared actions lookup mismatch',
@@ -238,7 +257,7 @@ const manifestExpose = manifest.exposes.find(
238257
);
239258
invariant(manifestExpose?.rsc, 'Expected expose rsc metadata in manifest');
240259
invariant(
241-
manifestExpose.rsc.lookup === 'rsbuild_container/button',
260+
manifestExpose.rsc.lookup === `${containerName}/button`,
242261
'Manifest expose lookup mismatch',
243262
);
244263

@@ -250,7 +269,7 @@ invariant(
250269
'Expected expose "./consumer" rsc metadata in manifest',
251270
);
252271
invariant(
253-
manifestConsumerExpose.rsc.lookup === 'rsbuild_container/consumer',
272+
manifestConsumerExpose.rsc.lookup === `${containerName}/consumer`,
254273
'Manifest expose "./consumer" lookup mismatch',
255274
);
256275

@@ -262,7 +281,7 @@ invariant(
262281
'Expected expose "./composed" rsc metadata in manifest',
263282
);
264283
invariant(
265-
manifestComposedExpose.rsc.lookup === 'rsbuild_container/composed',
284+
manifestComposedExpose.rsc.lookup === `${containerName}/composed`,
266285
'Manifest expose "./composed" lookup mismatch',
267286
);
268287

@@ -274,17 +293,13 @@ invariant(
274293
'Expected expose "./server-mixed" rsc metadata in manifest',
275294
);
276295
invariant(
277-
manifestServerMixedExpose.rsc.lookup === 'rsbuild_container/server-mixed',
296+
manifestServerMixedExpose.rsc.lookup === `${containerName}/server-mixed`,
278297
'Manifest expose "./server-mixed" lookup mismatch',
279298
);
280299

281-
const manifestRemote = manifest.remotes.find(
282-
(item) => item.alias === 'remote' && item.moduleName === 'Button',
283-
);
284-
invariant(manifestRemote?.rsc, 'Expected remote rsc metadata in manifest');
285300
invariant(
286-
manifestRemote.rsc.lookup === 'remote/Button',
287-
'Manifest remote lookup mismatch',
301+
Array.isArray(manifest.remotes) && manifest.remotes.length === 0,
302+
`Expected provider manifest remotes to be empty, got ${manifest.remotes.length}`,
288303
);
289304

290305
const expectedSingletonShares = [
@@ -304,12 +319,12 @@ for (const shareName of expectedSingletonShares) {
304319
}
305320

306321
invariant(
307-
clientStats.name === 'rsbuild_container',
308-
`Expected client stats container name "rsbuild_container", got "${clientStats.name}"`,
322+
clientStats.name === containerName,
323+
`Expected client stats container name "${containerName}", got "${clientStats.name}"`,
309324
);
310325
invariant(
311-
clientManifest.name === 'rsbuild_container',
312-
`Expected client manifest container name "rsbuild_container", got "${clientManifest.name}"`,
326+
clientManifest.name === containerName,
327+
`Expected client manifest container name "${containerName}", got "${clientManifest.name}"`,
313328
);
314329
invariant(
315330
clientStats.exposes.some((item) => item.path === './button'),

examples/rsbuild-rsc-federation-remote/src/exposed-client.tsx

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
'use client';
22

3-
import remoteButton from 'remote/Button';
43
import { MixedClientBadge, mixedValue } from 'rsbuild-rsc-federation-shared';
5-
import {
6-
composeExposeMessage,
7-
describeModuleType,
8-
localPatternTag,
9-
} from './local-patterns';
4+
import { composeExposeMessage, localPatternTag } from './local-patterns';
105

116
export default function ExposedButton() {
127
return composeExposeMessage([
138
'ExposedButton',
14-
describeModuleType(remoteButton),
15-
describeModuleType(MixedClientBadge),
9+
typeof MixedClientBadge,
1610
mixedValue.kind,
1711
localPatternTag,
1812
]);

examples/rsbuild-rsc-federation-remote/src/exposed-composed.tsx

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,18 @@
11
'use client';
22

3-
import remoteButton from 'remote/Button';
43
import {
54
MixedClientBadge,
65
mixedValue,
76
sharedValue,
87
} from 'rsbuild-rsc-federation-shared';
9-
import {
10-
composeExposeMessage,
11-
describeModuleType,
12-
localPatternTag,
13-
} from './local-patterns';
8+
import { composeExposeMessage, localPatternTag } from './local-patterns';
149

1510
export function describeComposedExpose() {
1611
return composeExposeMessage([
1712
'ComposedExpose',
1813
sharedValue,
1914
mixedValue.scope,
20-
describeModuleType(MixedClientBadge),
21-
describeModuleType(remoteButton),
15+
typeof MixedClientBadge,
2216
localPatternTag,
2317
]);
2418
}
Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
11
'use server';
22

3-
import remoteButton from 'remote/Button';
43
import { mixedValue, sharedValue } from 'rsbuild-rsc-federation-shared';
54
import {
65
mixedServerAction,
76
sharedAction,
87
} from 'rsbuild-rsc-federation-shared/server-actions';
9-
import { composeExposeMessage, describeModuleType } from './local-patterns';
8+
import { composeExposeMessage } from './local-patterns';
109

1110
export async function consumeRemoteAndShared() {
1211
await sharedAction();
1312
const mixedResponse = await mixedServerAction('consumer');
14-
return composeExposeMessage([
15-
sharedValue,
16-
mixedResponse,
17-
mixedValue.kind,
18-
describeModuleType(remoteButton),
19-
]);
13+
return composeExposeMessage([sharedValue, mixedResponse, mixedValue.kind]);
2014
}
Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
11
'use server';
22

3-
import remoteButton from 'remote/Button';
43
import { mixedValue } from 'rsbuild-rsc-federation-shared';
54
import { mixedServerAction } from 'rsbuild-rsc-federation-shared/server-actions';
6-
import { composeExposeMessage, describeModuleType } from './local-patterns';
5+
import { composeExposeMessage } from './local-patterns';
76

87
export async function consumeMixedPatterns() {
98
const mixedResponse = await mixedServerAction('server-mixed');
10-
return composeExposeMessage([
11-
mixedResponse,
12-
mixedValue.kind,
13-
describeModuleType(remoteButton),
14-
]);
9+
return composeExposeMessage([mixedResponse, mixedValue.kind]);
1510
}

examples/rsbuild-rsc-federation/e2e/app.spec.ts

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -98,25 +98,42 @@ for (const app of appUrls) {
9898
const sharedNames = stats.shared.map(
9999
(shared: { name: string }) => shared.name,
100100
);
101-
expect(sharedNames).toContain('rsc-shared-key');
102-
expect(sharedNames).toContain('rsc-shared-actions-key');
101+
expect(sharedNames).toContain('rsbuild-rsc-federation-shared');
102+
expect(sharedNames).toContain(
103+
'rsbuild-rsc-federation-shared/server-actions',
104+
);
103105

104106
const sharedActionsEntry = stats.shared.find(
105107
(shared: {
106108
name: string;
109+
shareKey?: string;
107110
rsc?: { serverActions?: Array<{ id: string; name: string }> };
108-
}) => shared.name === 'rsc-shared-actions-key',
111+
}) => shared.name === 'rsbuild-rsc-federation-shared/server-actions',
109112
);
113+
expect(sharedActionsEntry?.shareKey).toBe('rsc-shared-actions-key');
110114
expect(sharedActionsEntry?.rsc?.serverActions?.length).toBeGreaterThan(0);
111115

112-
const remoteEntry = stats.remotes.find(
113-
(remote: {
114-
alias: string;
115-
moduleName: string;
116-
rsc?: { lookup?: string };
117-
}) => remote.alias === 'remote' && remote.moduleName === 'Button',
118-
);
119-
expect(remoteEntry?.rsc?.lookup).toBe('remote/Button');
116+
if (app.name === 'host') {
117+
expect(stats.name).toBe('rsbuild_host');
118+
expect(manifest.name).toBe('rsbuild_host');
119+
expect(clientStats.name).toBe('rsbuild_host');
120+
expect(clientManifest.name).toBe('rsbuild_host');
121+
const remoteEntry = stats.remotes.find(
122+
(remote: {
123+
alias: string;
124+
moduleName: string;
125+
rsc?: { lookup?: string };
126+
}) => remote.alias === 'remote' && remote.moduleName === 'button',
127+
);
128+
expect(remoteEntry?.rsc?.lookup).toBe('remote/button');
129+
} else {
130+
expect(stats.name).toBe('rsbuild_remote');
131+
expect(manifest.name).toBe('rsbuild_remote');
132+
expect(clientStats.name).toBe('rsbuild_remote');
133+
expect(clientManifest.name).toBe('rsbuild_remote');
134+
expect(stats.remotes).toEqual([]);
135+
expect(manifest.remotes).toEqual([]);
136+
}
120137

121138
expect(remoteEntryText).toContain('server-mixed');
122139
expect(remoteEntryText).toContain('composed');

examples/rsbuild-rsc-federation/rsbuild.config.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { pluginReact } from '@rsbuild/plugin-react';
44
import { rspack } from '@rspack/core';
55
import { Layers, pluginRSC } from 'rsbuild-plugin-rsc';
66

7-
const containerName = 'rsbuild_container';
7+
const containerName = 'rsbuild_host';
88
type EnvironmentName = 'server' | 'client';
99

1010
const unifiedExposes = {
@@ -109,7 +109,9 @@ export default defineConfig({
109109
const isServerBuild = target === 'node';
110110
const environment: EnvironmentName = isServerBuild ? 'server' : 'client';
111111
const remotes = {
112-
remote: 'remote',
112+
remote: isServerBuild
113+
? 'remote@http://localhost:3331/mf-manifest.json'
114+
: 'remote@http://localhost:3331/mf-manifest.client.json',
113115
};
114116

115117
if (isServerBuild) {
@@ -124,6 +126,7 @@ export default defineConfig({
124126
library: isServerBuild
125127
? { type: 'commonjs-module' }
126128
: { type: 'var', name: containerName },
129+
remoteType: 'script',
127130
manifest: isServerBuild ? true : { fileName: 'mf-manifest.client' },
128131
exposes: resolveExposes(environment),
129132
remotes,

0 commit comments

Comments
 (0)