Skip to content

Commit 7df24df

Browse files
authored
feat: add init container hook (#1889)
1 parent 42184d7 commit 7df24df

File tree

9 files changed

+68
-54
lines changed

9 files changed

+68
-54
lines changed

.changeset/quick-chicken-glow.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@module-federation/runtime': patch
3+
---
4+
5+
only both version and name matched instance can be re-use

.changeset/wet-pillows-impress.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@module-federation/runtime': patch
3+
---
4+
5+
feat: add initContainer and beforeInitContainer hook

packages/runtime/src/core.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ import {
1010
ShareInfos,
1111
UserOptions,
1212
RemoteInfo,
13+
GlobalShareScope,
14+
InitScope,
15+
RemoteEntryInitOptions,
1316
} from './type';
1417
import {
1518
assert,
@@ -77,6 +80,21 @@ export class FederationHost {
7780
origin: FederationHost;
7881
}>('beforeRequest'),
7982
afterResolve: new AsyncWaterfallHook<LoadRemoteMatch>('afterResolve'),
83+
beforeInitContainer: new AsyncWaterfallHook<{
84+
shareScope: GlobalShareScope[string];
85+
initScope: InitScope;
86+
remoteEntryInitOptions: RemoteEntryInitOptions;
87+
remoteInfo: RemoteInfo;
88+
origin: FederationHost;
89+
}>('beforeInitContainer'),
90+
initContainer: new AsyncWaterfallHook<{
91+
shareScope: GlobalShareScope[string];
92+
initScope: InitScope;
93+
remoteEntryInitOptions: RemoteEntryInitOptions;
94+
remoteInfo: RemoteInfo;
95+
remoteEntryExports: RemoteEntryExports;
96+
origin: FederationHost;
97+
}>('initContainer'),
8098
onLoad: new AsyncHook<
8199
[
82100
{
@@ -409,14 +427,8 @@ export class FederationHost {
409427
let module: Module | undefined = this.moduleCache.get(remote.name);
410428

411429
const moduleOptions: ModuleOptions = {
412-
hostInfo: {
413-
name: this.options.name,
414-
version: this.options.version || 'custom',
415-
},
430+
host: this,
416431
remoteInfo,
417-
shared: this.options.shared || {},
418-
plugins: this.options.plugins,
419-
loaderHook: this.loaderHook,
420432
};
421433

422434
if (!module) {

packages/runtime/src/global.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,11 @@ export function getGlobalFederationInstance(
9797
return true;
9898
}
9999

100-
if (GMInstance.options.name === name && !version) {
100+
if (
101+
GMInstance.options.name === name &&
102+
!GMInstance.options.version &&
103+
!version
104+
) {
101105
return true;
102106
}
103107

packages/runtime/src/helpers.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
getGlobalHostPlugins,
1717
getPreloaded,
1818
setPreloaded,
19+
Global,
1920
} from './global';
2021
import { getGlobalShare, getGlobalShareScope } from './utils/share';
2122

@@ -29,6 +30,7 @@ const ShareUtils: IShareUtils = {
2930
};
3031

3132
interface IGlobalUtils {
33+
Global: typeof Global;
3234
nativeGlobal: typeof global;
3335
resetFederationGlobalInfo: typeof resetFederationGlobalInfo;
3436
getGlobalFederationInstance: typeof getGlobalFederationInstance;
@@ -49,6 +51,7 @@ interface IGlobalUtils {
4951
}
5052

5153
const GlobalUtils: IGlobalUtils = {
54+
Global,
5255
nativeGlobal,
5356
resetFederationGlobalInfo,
5457
getGlobalFederationInstance,

packages/runtime/src/module/index.ts

Lines changed: 26 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,45 +2,26 @@ import { getFMId, safeToString, assert } from '../utils';
22
import { getRemoteEntry } from '../utils/load';
33
import { FederationHost } from '../core';
44
import { Global } from '../global';
5-
import {
6-
RemoteEntryExports,
7-
Options,
8-
Remote,
9-
ShareInfos,
10-
RemoteInfo,
11-
} from '../type';
12-
import { composeKeyWithSeparator } from '@module-federation/sdk';
5+
import { RemoteEntryExports, RemoteInfo, InitScope } from '../type';
136

147
export type ModuleOptions = ConstructorParameters<typeof Module>[0];
158

16-
type HostInfo = Remote;
17-
189
class Module {
19-
hostInfo: HostInfo;
2010
remoteInfo: RemoteInfo;
2111
inited = false;
22-
shared: ShareInfos = {};
2312
remoteEntryExports?: RemoteEntryExports;
2413
lib: RemoteEntryExports | undefined = undefined;
25-
loaderHook: FederationHost['loaderHook'];
26-
// loading: Record<string, undefined | Promise<RemoteEntryExports | void>> = {};
14+
host: FederationHost;
2715

2816
constructor({
29-
hostInfo,
3017
remoteInfo,
31-
shared,
32-
loaderHook,
18+
host,
3319
}: {
34-
hostInfo: HostInfo;
3520
remoteInfo: RemoteInfo;
36-
shared: ShareInfos;
37-
plugins: Options['plugins'];
38-
loaderHook: FederationHost['loaderHook'];
21+
host: FederationHost;
3922
}) {
40-
this.hostInfo = hostInfo;
4123
this.remoteInfo = remoteInfo;
42-
this.shared = shared;
43-
this.loaderHook = loaderHook;
24+
this.host = host;
4425
}
4526

4627
async getEntry(): Promise<RemoteEntryExports> {
@@ -53,7 +34,7 @@ class Module {
5334
remoteInfo: this.remoteInfo,
5435
remoteEntryExports: this.remoteEntryExports,
5536
createScriptHook: (url: string) => {
56-
const res = this.loaderHook.lifecycle.createScript.emit({ url });
37+
const res = this.host.loaderHook.lifecycle.createScript.emit({ url });
5738
if (res instanceof HTMLScriptElement) {
5839
return res;
5940
}
@@ -84,29 +65,31 @@ class Module {
8465
globalShareScope[remoteShareScope] = {};
8566
}
8667
const shareScope = globalShareScope[remoteShareScope];
68+
const initScope: InitScope = [];
8769

88-
// TODO: compat logic , it could be moved after providing startup hooks
8970
const remoteEntryInitOptions = {
9071
version: this.remoteInfo.version || '',
91-
// @ts-ignore it will be passed by startup hooks
92-
region: this.hostInfo.region,
9372
};
94-
remoteEntryExports.init(shareScope, [], remoteEntryInitOptions);
95-
const federationInstance = Global.__FEDERATION__.__INSTANCES__.find(
96-
(i) =>
97-
i.options.id ===
98-
composeKeyWithSeparator(
99-
this.remoteInfo.name,
100-
this.remoteInfo.buildVersion,
101-
),
102-
);
103-
if (federationInstance) {
104-
federationInstance.initOptions({
105-
...remoteEntryInitOptions,
106-
remotes: [],
107-
name: this.remoteInfo.name,
73+
74+
const initContainerOptions =
75+
await this.host.hooks.lifecycle.beforeInitContainer.emit({
76+
shareScope,
77+
remoteEntryInitOptions,
78+
initScope,
79+
remoteInfo: this.remoteInfo,
80+
origin: this.host,
10881
});
109-
}
82+
83+
remoteEntryExports.init(
84+
initContainerOptions.shareScope,
85+
initContainerOptions.initScope,
86+
initContainerOptions.remoteEntryInitOptions,
87+
);
88+
89+
await this.host.hooks.lifecycle.initContainer.emit({
90+
...initContainerOptions,
91+
remoteEntryExports,
92+
});
11093
}
11194

11295
this.lib = remoteEntryExports;

packages/runtime/src/type/config.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,13 @@ export type RemoteEntryInitOptions = {
116116
version: string;
117117
};
118118

119+
export type InitScope = Array<Record<string, never>>;
120+
119121
export type RemoteEntryExports = {
120122
get: (id: string) => () => Promise<Module>;
121123
init: (
122124
shareScope: GlobalShareScope[string],
123-
initScope?: Array<Record<string, never>>,
125+
initScope?: InitScope,
124126
remoteEntryInitOPtions?: RemoteEntryInitOptions,
125127
) => void;
126128
};

packages/runtime/src/type/plugin.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ type SnapshotLifeCycleCyclePartial = Partial<{
1212
[k in keyof SnapshotLifeCycle]: Parameters<SnapshotLifeCycle[k]['on']>[0];
1313
}>;
1414

15-
type ModuleLifeCycle = Module['loaderHook']['lifecycle'];
15+
type ModuleLifeCycle = Module['host']['loaderHook']['lifecycle'];
1616
type ModuleLifeCycleCyclePartial = Partial<{
1717
[k in keyof ModuleLifeCycle]: Parameters<ModuleLifeCycle[k]['on']>[0];
1818
}>;

packages/runtime/src/utils/plugin.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export function registerPlugins(
88
hookInstances: Array<
99
| FederationHost['hooks']
1010
| FederationHost['snapshotHandler']['hooks']
11-
| Module['loaderHook']
11+
| Module['host']['loaderHook']
1212
>,
1313
) {
1414
const globalPlugins = getGlobalHostPlugins();

0 commit comments

Comments
 (0)