Skip to content

Commit 64ec2dc

Browse files
committed
feat(mf-runtime): supporting mf manifests
1 parent 00344c2 commit 64ec2dc

File tree

1 file changed

+90
-2
lines changed

1 file changed

+90
-2
lines changed

libs/mf-runtime/src/lib/loader/dynamic-federation.ts

+90-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,21 @@ type Container = {
77
get(module: string): Factory;
88
};
99

10+
let config: ParsedMfConfigFile = {};
11+
12+
export type DynamicMfConfigFile = {
13+
[key: string]: string | DynamicMfConfig
14+
};
15+
16+
export type ParsedMfConfigFile = {
17+
[key: string]: DynamicMfConfig
18+
};
19+
20+
export type DynamicMfConfig = {
21+
type: 'module' | 'script',
22+
remoteEntry: string
23+
};
24+
1025
declare const __webpack_init_sharing__: (shareScope: string) => Promise<void>;
1126
declare const __webpack_share_scopes__: { default: Scope };
1227

@@ -108,7 +123,7 @@ async function loadRemoteScriptEntry(remoteEntry: string, remoteName: string): P
108123
});
109124
}
110125

111-
export type LoadRemoteModuleOptions = LoadRemoteModuleScriptOptions | LoadRemoteModuleEsmOptions;
126+
export type LoadRemoteModuleOptions = LoadRemoteModuleScriptOptions | LoadRemoteModuleEsmOptions | LoadRemoteModuleManifestOptions;
112127

113128
export type LoadRemoteModuleScriptOptions = {
114129
type?: 'script';
@@ -123,17 +138,41 @@ export type LoadRemoteModuleEsmOptions = {
123138
exposedModule: string;
124139
}
125140

141+
export type LoadRemoteModuleManifestOptions = {
142+
type: 'manifest';
143+
remoteName: string;
144+
exposedModule: string;
145+
}
146+
126147
// eslint-disable-next-line @typescript-eslint/no-explicit-any
127148
export async function loadRemoteModule<T = any>(options: LoadRemoteModuleOptions): Promise<T> {
128149

129150
let loadRemoteEntryOptions: LoadRemoteEntryOptions;
130151
let key: string;
152+
let remoteEntry: string;
131153

132154
// To support legacy API (< ng 13)
133155
if (!options.type) {
134156
options.type = 'script';
135157
}
136158

159+
if (options.type === 'manifest') {
160+
const manifestEntry = config[options.remoteName];
161+
if (!manifestEntry) {
162+
throw new Error('Manifest does not contain ' + options.remoteName);
163+
}
164+
options = {
165+
type: manifestEntry.type,
166+
exposedModule: options.exposedModule,
167+
remoteEntry: manifestEntry.remoteEntry,
168+
remoteName: (manifestEntry.type === 'script') ? options.remoteName : undefined
169+
}
170+
remoteEntry = manifestEntry.remoteEntry;
171+
}
172+
else {
173+
remoteEntry = options.remoteEntry;
174+
}
175+
137176
if (options.type === 'script') {
138177
loadRemoteEntryOptions = {
139178
type: 'script',
@@ -150,9 +189,58 @@ export async function loadRemoteModule<T = any>(options: LoadRemoteModuleOptions
150189
key = options.remoteEntry;
151190
}
152191

153-
if (options.remoteEntry) {
192+
if (remoteEntry) {
154193
await loadRemoteEntry(loadRemoteEntryOptions);
155194
}
156195

157196
return await lookupExposedModule<T>(key, options.exposedModule);
158197
}
198+
199+
export async function loadManifest(configFile: string, skipRemoteEntries = false): Promise<void> {
200+
201+
const result = await fetch(configFile);
202+
203+
if (!result.ok) {
204+
throw Error('could not load configFile: ' + configFile);
205+
}
206+
207+
config = parseConfig(await result.json());
208+
209+
if (!skipRemoteEntries) {
210+
await loadRemoteEntries();
211+
}
212+
}
213+
214+
function parseConfig(config: DynamicMfConfigFile): ParsedMfConfigFile {
215+
const result: ParsedMfConfigFile = {};
216+
for (let key in config) {
217+
const value = config[key];
218+
219+
let entry: DynamicMfConfig;
220+
if (typeof value === 'string') {
221+
entry = {
222+
remoteEntry: value,
223+
type: 'module'
224+
};
225+
}
226+
else {
227+
entry = value;
228+
}
229+
230+
result[key] = entry;
231+
}
232+
return result;
233+
}
234+
235+
async function loadRemoteEntries() {
236+
for (let key in config) {
237+
const entry = config[key];
238+
239+
if (entry.type === 'module') {
240+
await loadRemoteEntry({ type: 'module', remoteEntry: entry.remoteEntry });
241+
}
242+
else {
243+
await loadRemoteEntry({ type: 'script', remoteEntry: entry.remoteEntry, remoteName: key });
244+
}
245+
}
246+
}

0 commit comments

Comments
 (0)