Skip to content

Commit 01a3fc8

Browse files
committed
feat: use remoteLoadingData directly
1 parent 6fc7f13 commit 01a3fc8

File tree

9 files changed

+351
-255
lines changed

9 files changed

+351
-255
lines changed

packages/enhanced/src/lib/container/RemoteRuntimeModule.ts

Lines changed: 12 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import RemoteModule from './RemoteModule';
88
import { getFederationGlobalScope } from './runtime/utils';
99
import type ExternalModule from 'webpack/lib/ExternalModule';
1010
import type FallbackModule from './FallbackModule';
11-
import type { RemotesOptions } from '@module-federation/webpack-bundler-runtime';
11+
import type { ModuleIdToRemoteDataMapping } from '@module-federation/webpack-bundler-runtime';
1212

1313
const extractUrlAndGlobal = require(
1414
normalizeWebpackPath('webpack/lib/util/extractUrlAndGlobal'),
@@ -30,19 +30,7 @@ class RemoteRuntimeModule extends RuntimeModule {
3030
const { compilation, chunkGraph } = this;
3131
const { runtimeTemplate, moduleGraph } = compilation as Compilation;
3232
const chunkToRemotesMapping: Record<string, any> = {};
33-
const idToExternalAndNameMapping: Record<string | number, any> = {};
34-
const idToRemoteMap: RemotesOptions['idToRemoteMap'] = {};
35-
// let chunkReferences: Set<Chunk> = new Set();
36-
37-
// if (this.chunk && chunkGraph) {
38-
// const requirements = chunkGraph.getTreeRuntimeRequirements(this.chunk);
39-
// if (requirements.has('federation-entry-startup')) {
40-
// chunkReferences = this.chunk.getAllReferencedChunks();
41-
// } else {
42-
// // remote entry doesnt need federation startup, can have async chunk map only
43-
// chunkReferences = this.chunk.getAllAsyncChunks();
44-
// }
45-
// }
33+
const moduleIdToRemoteDataMapping: ModuleIdToRemoteDataMapping = {};
4634

4735
const allChunks = [
4836
...Array.from(this.chunk?.getAllReferencedChunks() || []),
@@ -78,7 +66,12 @@ class RemoteRuntimeModule extends RuntimeModule {
7866
//@ts-ignore
7967
remotes.push(id);
8068

81-
idToExternalAndNameMapping[id] = [shareScope, name, externalModuleId];
69+
moduleIdToRemoteDataMapping[id] = {
70+
shareScope: shareScope as string,
71+
name,
72+
externalModuleId: externalModuleId as string,
73+
remoteName: '',
74+
};
8275
const remoteModules: ExternalModule[] = [];
8376
// FallbackModule has requests
8477
if ('requests' in externalModule && externalModule.requests) {
@@ -93,7 +86,6 @@ class RemoteRuntimeModule extends RuntimeModule {
9386
remoteModules.push(externalModule as ExternalModule);
9487
}
9588

96-
idToRemoteMap[id] = [];
9789
remoteModules.forEach((remoteModule) => {
9890
let remoteName = '';
9991
try {
@@ -104,17 +96,6 @@ class RemoteRuntimeModule extends RuntimeModule {
10496
} catch (err) {
10597
//noop
10698
}
107-
const externalModuleId =
108-
chunkGraph &&
109-
remoteModule &&
110-
// @ts-ignore
111-
chunkGraph.getModuleId(remoteModule);
112-
113-
idToRemoteMap[id].push({
114-
externalType: remoteModule.externalType,
115-
name: remoteModule.externalType === 'script' ? remoteName : '',
116-
externalModuleId,
117-
});
11899
});
119100
}
120101
}
@@ -124,22 +105,20 @@ class RemoteRuntimeModule extends RuntimeModule {
124105
);
125106

126107
return Template.asString([
127-
`var chunkMapping = ${JSON.stringify(
108+
`${RuntimeGlobals.require}.remotesLoadingData.chunkMapping = ${JSON.stringify(
128109
chunkToRemotesMapping,
129110
null,
130111
'\t',
131112
)};`,
132-
`var idToExternalAndNameMapping = ${JSON.stringify(
133-
idToExternalAndNameMapping,
113+
`${RuntimeGlobals.require}.remotesLoadingData.moduleIdToRemoteDataMapping = ${JSON.stringify(
114+
moduleIdToRemoteDataMapping,
134115
null,
135116
'\t',
136117
)};`,
137-
`var idToRemoteMap = ${JSON.stringify(idToRemoteMap, null, '\t')};`,
138-
`${federationGlobal}.bundlerRuntimeOptions.remotes = {idToRemoteMap,chunkMapping, idToExternalAndNameMapping, webpackRequire:${RuntimeGlobals.require}};`,
139118
`${
140119
RuntimeGlobals.ensureChunkHandlers
141120
}.remotes = ${runtimeTemplate.basicFunction('chunkId, promises', [
142-
`${federationGlobal}.bundlerRuntime.remotes({idToRemoteMap,chunkMapping, idToExternalAndNameMapping, chunkId, promises, webpackRequire:${RuntimeGlobals.require}});`,
121+
`${federationGlobal}.bundlerRuntime.remotes({ chunkId, promises, webpackRequire:${RuntimeGlobals.require}});`,
143122
])}`,
144123
]);
145124
}

packages/enhanced/src/lib/container/runtime/getFederationGlobal.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { normalizeWebpackPath } from '@module-federation/sdk/normalize-webpack-p
22
import { getFederationGlobalScope } from './utils';
33
import type RuntimeGlobals from 'webpack/lib/RuntimeGlobals';
44
import { NormalizedRuntimeInitOptionsWithOutShared } from '../../../types/runtime';
5+
import type { RemoteInfos } from '@module-federation/webpack-bundler-runtime';
56

67
const { Template } = require(
78
normalizeWebpackPath('webpack'),
@@ -15,7 +16,29 @@ function getFederationGlobal(
1516
initOptionsWithoutShared: NormalizedRuntimeInitOptionsWithOutShared,
1617
): string {
1718
const federationGlobal = getFederationGlobalScope(runtimeGlobals);
18-
const initOptionsStrWithoutShared = JSON.stringify(initOptionsWithoutShared);
19+
const initOptionsStrWithoutShared = JSON.stringify({
20+
...initOptionsWithoutShared,
21+
remotes: initOptionsWithoutShared.remotes.filter(
22+
(remote) => remote.externalType === 'script',
23+
),
24+
});
25+
const remoteInfos = JSON.stringify(
26+
initOptionsWithoutShared.remotes.reduce((acc, remote) => {
27+
const item: RemoteInfos[string][0] = {
28+
alias: remote.alias || '',
29+
name: remote.name,
30+
// @ts-ignore
31+
entry: remote.entry || '',
32+
// @ts-ignore
33+
shareScope: remote.shareScope,
34+
externalType: remote.externalType,
35+
};
36+
const key = remote.name || remote.alias || '';
37+
acc[key] ||= [];
38+
acc[key].push(item);
39+
return acc;
40+
}, {} as RemoteInfos),
41+
);
1942

2043
return template.asString([
2144
`if(!${federationGlobal}){`,
@@ -25,11 +48,12 @@ function getFederationGlobal(
2548
`initOptions: ${initOptionsStrWithoutShared},`,
2649
`chunkMatcher: function(chunkId) {return ${matcher}},`,
2750
`rootOutputDir: ${JSON.stringify(rootOutputDir || '')},`,
28-
'bundlerRuntimeOptions: {}',
51+
`bundlerRuntimeOptions: { remotes: { remoteInfos: ${remoteInfos}, webpackRequire: ${runtimeGlobals.require} } }`,
2952
]),
3053
'};',
3154
]),
3255
`${runtimeGlobals.require}.consumesLoadingData = {}`,
56+
`${runtimeGlobals.require}.remotesLoadingData = {}`,
3357
'}',
3458
]);
3559
}

packages/enhanced/src/lib/container/runtime/utils.ts

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import upath from 'upath';
77
import path from 'path';
88
import crypto from 'crypto';
99
import { parseOptions } from '../options';
10-
import type { init } from '@module-federation/runtime-tools';
1110
import type webpack from 'webpack';
1211
import type RuntimeGlobals from 'webpack/lib/RuntimeGlobals';
1312
import type { moduleFederationPlugin } from '@module-federation/sdk';
@@ -21,8 +20,6 @@ type EntryStaticNormalized = Awaited<
2120
ReturnType<Extract<webpack.WebpackOptionsNormalized['entry'], () => any>>
2221
>;
2322

24-
type Remotes = Parameters<typeof init>[0]['remotes'];
25-
2623
interface ModifyEntryOptions {
2724
compiler: webpack.Compiler;
2825
prependEntry?: (entry: EntryStaticNormalized) => void;
@@ -49,27 +46,47 @@ export function normalizeRuntimeInitOptionsWithOutShared(
4946
shareScope: item.shareScope || options.shareScope || 'default',
5047
}),
5148
);
52-
const remoteOptions: Remotes = [];
49+
const remoteOptions: NormalizedRuntimeInitOptionsWithOutShared['remotes'] =
50+
[];
5351
parsedOptions.forEach((parsedOption) => {
5452
const [alias, remoteInfos] = parsedOption;
5553
const { external, shareScope } = remoteInfos;
56-
try {
57-
// only fit for remoteType: 'script'
58-
const entry = external[0];
59-
if (/\s/.test(entry)) {
54+
external.forEach((externalItem) => {
55+
try {
56+
const entry = externalItem;
57+
if (/\s/.test(entry)) {
58+
return;
59+
}
60+
const [url, globalName] = extractUrlAndGlobal(externalItem);
61+
remoteOptions.push({
62+
alias,
63+
name: globalName,
64+
entry: url,
65+
shareScope: shareScope,
66+
externalType: 'script',
67+
});
68+
} catch (err) {
69+
const getExternalTypeFromExternal = (external: string) => {
70+
if (/^[a-z0-9-]+ /.test(external)) {
71+
const idx = external.indexOf(' ');
72+
return [
73+
external.slice(0, idx) as moduleFederationPlugin.ExternalsType,
74+
external.slice(idx + 1),
75+
] as const;
76+
}
77+
return null;
78+
};
79+
remoteOptions.push({
80+
alias,
81+
name: '',
82+
entry: '',
83+
shareScope: shareScope,
84+
// @ts-ignore
85+
externalType: getExternalTypeFromExternal(externalItem) || 'unknown',
86+
});
6087
return;
6188
}
62-
const [url, globalName] = extractUrlAndGlobal(external[0]);
63-
remoteOptions.push({
64-
alias,
65-
name: globalName,
66-
entry: url,
67-
shareScope: shareScope,
68-
// externalType
69-
});
70-
} catch (err) {
71-
return;
72-
}
89+
});
7390
});
7491

7592
const initOptionsWithoutShared = {
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import type { init } from '@module-federation/runtime-tools';
2+
import type { moduleFederationPlugin } from '@module-federation/sdk';
23

34
type Remotes = Parameters<typeof init>[0]['remotes'];
45

56
export interface NormalizedRuntimeInitOptionsWithOutShared {
67
name: string;
7-
remotes: Remotes;
8+
remotes: Array<
9+
Remotes[0] & { externalType: moduleFederationPlugin.ExternalsType }
10+
>;
811
}

0 commit comments

Comments
 (0)