@tramvai/module-child-app 5.49.1 → 6.59.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser/loader.browser.js +18 -5
- package/lib/browser/loader.d.ts +10 -2
- package/lib/browser/preload.browser.js +85 -29
- package/lib/browser/preload.d.ts +14 -2
- package/lib/browser/providers.browser.js +17 -2
- package/lib/browser/render.browser.js +15 -1
- package/lib/browser/render.d.ts +10 -2
- package/lib/browser/runCommand.browser.js +1 -1
- package/lib/browser/runCommand.d.ts +1 -1
- package/lib/browser/timing.browser.js +100 -0
- package/lib/browser/timing.d.ts +4 -0
- package/lib/browser.js +2 -1
- package/lib/contracts/contractManager.base.browser.js +4 -0
- package/lib/contracts/contractManager.base.es.js +4 -0
- package/lib/contracts/contractManager.base.js +4 -0
- package/lib/contracts/contractManager.server.es.js +1 -0
- package/lib/contracts/contractManager.server.js +1 -0
- package/lib/server/cache/cache.d.ts +39 -0
- package/lib/server/cache/cache.es.js +76 -0
- package/lib/server/cache/cache.js +80 -0
- package/lib/server/cache/cacheCleanup.d.ts +4 -0
- package/lib/server/cache/cacheCleanup.es.js +16 -0
- package/lib/server/cache/cacheCleanup.js +21 -0
- package/lib/server/loader.d.ts +14 -7
- package/lib/server/loader.es.js +34 -19
- package/lib/server/loader.js +34 -19
- package/lib/server/module-federation/best-loaded-shared-modules.d.ts +15 -0
- package/lib/server/module-federation/best-loaded-shared-modules.es.js +26 -0
- package/lib/server/module-federation/best-loaded-shared-modules.js +30 -0
- package/lib/server/module-federation/best-shared-modules.d.ts +15 -0
- package/lib/server/module-federation/utils.d.ts +18 -0
- package/lib/server/module-federation/utils.es.js +38 -0
- package/lib/server/module-federation/utils.js +43 -0
- package/lib/server/preload.d.ts +13 -2
- package/lib/server/preload.es.js +58 -19
- package/lib/server/preload.js +58 -19
- package/lib/server/providers.es.js +17 -4
- package/lib/server/providers.js +14 -1
- package/lib/server/render-slots.es.js +62 -50
- package/lib/server/render-slots.js +62 -50
- package/lib/server/render.d.ts +9 -2
- package/lib/server/render.es.js +13 -2
- package/lib/server/render.js +13 -2
- package/lib/server/stateManager.es.js +3 -1
- package/lib/server/stateManager.js +3 -1
- package/lib/shared/command.browser.js +4 -0
- package/lib/shared/command.es.js +4 -0
- package/lib/shared/command.js +4 -0
- package/lib/shared/di.browser.js +5 -1
- package/lib/shared/di.es.js +5 -1
- package/lib/shared/di.js +5 -1
- package/lib/shared/pageService.browser.js +8 -3
- package/lib/shared/pageService.es.js +8 -3
- package/lib/shared/pageService.js +8 -3
- package/lib/shared/providers.browser.js +8 -3
- package/lib/shared/providers.es.js +8 -3
- package/lib/shared/providers.js +6 -1
- package/lib/shared/react/ChildAppErrorBoundary/ChildAppErrorBoundary.browser.js +56 -0
- package/lib/shared/react/ChildAppErrorBoundary/ChildAppErrorBoundary.d.ts +45 -0
- package/lib/shared/react/ChildAppErrorBoundary/ChildAppErrorBoundary.es.js +56 -0
- package/lib/shared/react/ChildAppErrorBoundary/ChildAppErrorBoundary.js +60 -0
- package/lib/shared/react/ChildAppErrorBoundary/FallbackError.browser.js +21 -0
- package/lib/shared/react/ChildAppErrorBoundary/FallbackError.d.ts +5 -0
- package/lib/shared/react/ChildAppErrorBoundary/FallbackError.es.js +21 -0
- package/lib/shared/react/ChildAppErrorBoundary/FallbackError.js +25 -0
- package/lib/shared/react/ChildAppFallbackWrapper.browser.js +14 -0
- package/lib/shared/react/ChildAppFallbackWrapper.d.ts +10 -0
- package/lib/shared/react/ChildAppFallbackWrapper.es.js +14 -0
- package/lib/shared/react/ChildAppFallbackWrapper.js +18 -0
- package/lib/shared/react/childAppErrorBoundaryWrapper.browser.js +22 -0
- package/lib/shared/react/childAppErrorBoundaryWrapper.d.ts +8 -0
- package/lib/shared/react/childAppErrorBoundaryWrapper.es.js +22 -0
- package/lib/shared/react/childAppErrorBoundaryWrapper.js +26 -0
- package/lib/shared/react/component.browser.js +31 -6
- package/lib/shared/react/component.es.js +31 -6
- package/lib/shared/react/component.js +29 -4
- package/lib/shared/resolutionConfigManager.browser.js +35 -15
- package/lib/shared/resolutionConfigManager.d.ts +8 -2
- package/lib/shared/resolutionConfigManager.es.js +35 -15
- package/lib/shared/resolutionConfigManager.js +35 -15
- package/lib/shared/singletonDi.browser.js +18 -2
- package/lib/shared/singletonDi.d.ts +1 -0
- package/lib/shared/singletonDi.es.js +18 -2
- package/lib/shared/singletonDi.js +18 -2
- package/lib/shared/store.browser.js +15 -2
- package/lib/shared/store.d.ts +6 -0
- package/lib/shared/store.es.js +15 -2
- package/lib/shared/store.js +15 -1
- package/lib/shared/webpack/moduleFederation.browser.js +42 -0
- package/lib/shared/webpack/moduleFederation.d.ts +27 -18
- package/lib/shared/webpack/moduleFederation.es.js +42 -0
- package/lib/shared/webpack/moduleFederation.js +42 -0
- package/package.json +22 -23
- package/lib/shared/react/childAppErrorBoundary.browser.js +0 -14
- package/lib/shared/react/childAppErrorBoundary.d.ts +0 -8
- package/lib/shared/react/childAppErrorBoundary.es.js +0 -14
- package/lib/shared/react/childAppErrorBoundary.js +0 -18
package/lib/server/preload.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Route } from '@tinkoff/router';
|
|
2
|
-
import {
|
|
2
|
+
import { AsyncTapableHookInstance, TAPABLE_HOOK_FACTORY_TOKEN } from '@tramvai/core';
|
|
3
|
+
import { type ChildAppCommandLineRunner, type ChildAppRequestConfig, type ChildAppLoader, type ChildAppPreloadManager, type ChildAppStateManager, type CHILD_APP_RESOLVE_CONFIG_TOKEN, type ChildAppFinalConfig, type CHILD_APP_RESOLUTION_CONFIG_MANAGER_TOKEN, type CHILD_APP_DI_MANAGER_TOKEN, CHILD_APP_PRELOAD_MANAGER_PLUGIN, PreloadArgs, RunChildAppCommandLineArgs } from '@tramvai/tokens-child-app';
|
|
3
4
|
export declare class PreloadManager implements ChildAppPreloadManager {
|
|
4
5
|
private loader;
|
|
5
6
|
private runner;
|
|
@@ -10,14 +11,24 @@ export declare class PreloadManager implements ChildAppPreloadManager {
|
|
|
10
11
|
private shouldRunImmediately;
|
|
11
12
|
private map;
|
|
12
13
|
private preloadMap;
|
|
13
|
-
|
|
14
|
+
private hookFactory;
|
|
15
|
+
hooks: {
|
|
16
|
+
preloadChildApp: AsyncTapableHookInstance<PreloadArgs>;
|
|
17
|
+
prefetchChildApp: AsyncTapableHookInstance<PreloadArgs>;
|
|
18
|
+
runChildAppCommandLine: AsyncTapableHookInstance<RunChildAppCommandLineArgs>;
|
|
19
|
+
};
|
|
20
|
+
constructor({ loader, runner, stateManager, resolutionConfigManager, resolveFullConfig, diManager, hookFactory, plugins, }: {
|
|
14
21
|
loader: ChildAppLoader;
|
|
15
22
|
runner: ChildAppCommandLineRunner;
|
|
16
23
|
stateManager: ChildAppStateManager;
|
|
17
24
|
resolutionConfigManager: typeof CHILD_APP_RESOLUTION_CONFIG_MANAGER_TOKEN;
|
|
18
25
|
resolveFullConfig: typeof CHILD_APP_RESOLVE_CONFIG_TOKEN;
|
|
19
26
|
diManager: typeof CHILD_APP_DI_MANAGER_TOKEN;
|
|
27
|
+
hookFactory: typeof TAPABLE_HOOK_FACTORY_TOKEN;
|
|
28
|
+
plugins: (typeof CHILD_APP_PRELOAD_MANAGER_PLUGIN)[] | null;
|
|
20
29
|
});
|
|
30
|
+
private runChildAppCommandLineHook;
|
|
31
|
+
private preloadChildAppHook;
|
|
21
32
|
preload(request: ChildAppRequestConfig, route?: Route): Promise<void>;
|
|
22
33
|
prefetch(request: ChildAppRequestConfig, route?: Route): Promise<void>;
|
|
23
34
|
isPreloaded(request: ChildAppRequestConfig): boolean;
|
package/lib/server/preload.es.js
CHANGED
|
@@ -2,28 +2,53 @@ import { optional } from '@tinkoff/dippy';
|
|
|
2
2
|
import { CHILD_APP_PAGE_SERVICE_TOKEN } from '@tramvai/tokens-child-app';
|
|
3
3
|
|
|
4
4
|
class PreloadManager {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
loader;
|
|
6
|
+
runner;
|
|
7
|
+
stateManager;
|
|
8
|
+
resolutionConfigManager;
|
|
9
|
+
resolveFullConfig;
|
|
10
|
+
diManager;
|
|
11
|
+
shouldRunImmediately = false;
|
|
12
|
+
map = new Map();
|
|
13
|
+
preloadMap = new Map();
|
|
14
|
+
hookFactory;
|
|
15
|
+
hooks;
|
|
16
|
+
constructor({ loader, runner, stateManager, resolutionConfigManager, resolveFullConfig, diManager, hookFactory, plugins, }) {
|
|
9
17
|
this.loader = loader;
|
|
10
18
|
this.runner = runner;
|
|
11
19
|
this.stateManager = stateManager;
|
|
12
20
|
this.resolutionConfigManager = resolutionConfigManager;
|
|
13
21
|
this.resolveFullConfig = resolveFullConfig;
|
|
14
22
|
this.diManager = diManager;
|
|
23
|
+
this.hookFactory = hookFactory;
|
|
24
|
+
this.hooks = {
|
|
25
|
+
preloadChildApp: this.hookFactory.createAsync('preloadChildApp'),
|
|
26
|
+
prefetchChildApp: this.hookFactory.createAsync('prefetchChildApp'),
|
|
27
|
+
runChildAppCommandLine: this.hookFactory.createAsync('runChildAppCommandLine'),
|
|
28
|
+
};
|
|
29
|
+
this.hooks.preloadChildApp.tapPromise('childAppPreload', async (_, payload) => {
|
|
30
|
+
await this.preloadChildAppHook(payload);
|
|
31
|
+
});
|
|
32
|
+
this.hooks.prefetchChildApp.tapPromise('childAppPrefetch', async () => {
|
|
33
|
+
// do nothing at server side
|
|
34
|
+
});
|
|
35
|
+
this.hooks.runChildAppCommandLine.tapPromise('childAppCommandRun', async (_, payload) => {
|
|
36
|
+
await this.runChildAppCommandLineHook(payload);
|
|
37
|
+
});
|
|
38
|
+
plugins?.forEach((plugin) => {
|
|
39
|
+
plugin.apply(this.hooks);
|
|
40
|
+
});
|
|
15
41
|
}
|
|
16
|
-
async
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
if (!config) {
|
|
42
|
+
async runChildAppCommandLineHook({ config, status, }) {
|
|
43
|
+
const childApp = this.loader.get(config);
|
|
44
|
+
if (!childApp) {
|
|
20
45
|
return;
|
|
21
46
|
}
|
|
47
|
+
await this.runner.run('server', status, config);
|
|
48
|
+
await this.stateManager.registerChildApp(config);
|
|
49
|
+
}
|
|
50
|
+
async preloadChildAppHook({ config }) {
|
|
22
51
|
const { key } = config;
|
|
23
|
-
if (this.map.has(key)) {
|
|
24
|
-
await this.map.get(key);
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
52
|
const promise = this.loader
|
|
28
53
|
.load(config)
|
|
29
54
|
.catch(() => {
|
|
@@ -47,8 +72,23 @@ class PreloadManager {
|
|
|
47
72
|
await promise;
|
|
48
73
|
}
|
|
49
74
|
}
|
|
75
|
+
async preload(request, route) {
|
|
76
|
+
await this.resolutionConfigManager.init();
|
|
77
|
+
const config = this.resolveFullConfig(request);
|
|
78
|
+
if (!config) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const { key } = config;
|
|
82
|
+
if (this.map.has(key)) {
|
|
83
|
+
await this.map.get(key);
|
|
84
|
+
}
|
|
85
|
+
await this.hooks.preloadChildApp.callPromise({
|
|
86
|
+
config,
|
|
87
|
+
route,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
50
90
|
async prefetch(request, route) {
|
|
51
|
-
// do nothing
|
|
91
|
+
// do nothing on server side
|
|
52
92
|
}
|
|
53
93
|
isPreloaded(request) {
|
|
54
94
|
const config = this.resolveFullConfig(request);
|
|
@@ -78,12 +118,11 @@ class PreloadManager {
|
|
|
78
118
|
return Array.from(this.preloadMap.values());
|
|
79
119
|
}
|
|
80
120
|
async run(status, config) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
await this.stateManager.registerChildApp(config);
|
|
121
|
+
await this.hooks.runChildAppCommandLine.callPromise({
|
|
122
|
+
config,
|
|
123
|
+
status,
|
|
124
|
+
line: 'server',
|
|
125
|
+
});
|
|
87
126
|
}
|
|
88
127
|
saveNotPreloadedForSpaNavigation(request) {
|
|
89
128
|
// do nothing at server-side
|
package/lib/server/preload.js
CHANGED
|
@@ -6,28 +6,53 @@ var dippy = require('@tinkoff/dippy');
|
|
|
6
6
|
var tokensChildApp = require('@tramvai/tokens-child-app');
|
|
7
7
|
|
|
8
8
|
class PreloadManager {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
loader;
|
|
10
|
+
runner;
|
|
11
|
+
stateManager;
|
|
12
|
+
resolutionConfigManager;
|
|
13
|
+
resolveFullConfig;
|
|
14
|
+
diManager;
|
|
15
|
+
shouldRunImmediately = false;
|
|
16
|
+
map = new Map();
|
|
17
|
+
preloadMap = new Map();
|
|
18
|
+
hookFactory;
|
|
19
|
+
hooks;
|
|
20
|
+
constructor({ loader, runner, stateManager, resolutionConfigManager, resolveFullConfig, diManager, hookFactory, plugins, }) {
|
|
13
21
|
this.loader = loader;
|
|
14
22
|
this.runner = runner;
|
|
15
23
|
this.stateManager = stateManager;
|
|
16
24
|
this.resolutionConfigManager = resolutionConfigManager;
|
|
17
25
|
this.resolveFullConfig = resolveFullConfig;
|
|
18
26
|
this.diManager = diManager;
|
|
27
|
+
this.hookFactory = hookFactory;
|
|
28
|
+
this.hooks = {
|
|
29
|
+
preloadChildApp: this.hookFactory.createAsync('preloadChildApp'),
|
|
30
|
+
prefetchChildApp: this.hookFactory.createAsync('prefetchChildApp'),
|
|
31
|
+
runChildAppCommandLine: this.hookFactory.createAsync('runChildAppCommandLine'),
|
|
32
|
+
};
|
|
33
|
+
this.hooks.preloadChildApp.tapPromise('childAppPreload', async (_, payload) => {
|
|
34
|
+
await this.preloadChildAppHook(payload);
|
|
35
|
+
});
|
|
36
|
+
this.hooks.prefetchChildApp.tapPromise('childAppPrefetch', async () => {
|
|
37
|
+
// do nothing at server side
|
|
38
|
+
});
|
|
39
|
+
this.hooks.runChildAppCommandLine.tapPromise('childAppCommandRun', async (_, payload) => {
|
|
40
|
+
await this.runChildAppCommandLineHook(payload);
|
|
41
|
+
});
|
|
42
|
+
plugins?.forEach((plugin) => {
|
|
43
|
+
plugin.apply(this.hooks);
|
|
44
|
+
});
|
|
19
45
|
}
|
|
20
|
-
async
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (!config) {
|
|
46
|
+
async runChildAppCommandLineHook({ config, status, }) {
|
|
47
|
+
const childApp = this.loader.get(config);
|
|
48
|
+
if (!childApp) {
|
|
24
49
|
return;
|
|
25
50
|
}
|
|
51
|
+
await this.runner.run('server', status, config);
|
|
52
|
+
await this.stateManager.registerChildApp(config);
|
|
53
|
+
}
|
|
54
|
+
async preloadChildAppHook({ config }) {
|
|
26
55
|
const { key } = config;
|
|
27
|
-
if (this.map.has(key)) {
|
|
28
|
-
await this.map.get(key);
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
56
|
const promise = this.loader
|
|
32
57
|
.load(config)
|
|
33
58
|
.catch(() => {
|
|
@@ -51,8 +76,23 @@ class PreloadManager {
|
|
|
51
76
|
await promise;
|
|
52
77
|
}
|
|
53
78
|
}
|
|
79
|
+
async preload(request, route) {
|
|
80
|
+
await this.resolutionConfigManager.init();
|
|
81
|
+
const config = this.resolveFullConfig(request);
|
|
82
|
+
if (!config) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const { key } = config;
|
|
86
|
+
if (this.map.has(key)) {
|
|
87
|
+
await this.map.get(key);
|
|
88
|
+
}
|
|
89
|
+
await this.hooks.preloadChildApp.callPromise({
|
|
90
|
+
config,
|
|
91
|
+
route,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
54
94
|
async prefetch(request, route) {
|
|
55
|
-
// do nothing
|
|
95
|
+
// do nothing on server side
|
|
56
96
|
}
|
|
57
97
|
isPreloaded(request) {
|
|
58
98
|
const config = this.resolveFullConfig(request);
|
|
@@ -82,12 +122,11 @@ class PreloadManager {
|
|
|
82
122
|
return Array.from(this.preloadMap.values());
|
|
83
123
|
}
|
|
84
124
|
async run(status, config) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
await this.stateManager.registerChildApp(config);
|
|
125
|
+
await this.hooks.runChildAppCommandLine.callPromise({
|
|
126
|
+
config,
|
|
127
|
+
status,
|
|
128
|
+
line: 'server',
|
|
129
|
+
});
|
|
91
130
|
}
|
|
92
131
|
saveNotPreloadedForSpaNavigation(request) {
|
|
93
132
|
// do nothing at server-side
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { combineValidators, isUrl, endsWith } from '@tinkoff/env-validators';
|
|
2
2
|
import { Scope, optional, DI_TOKEN } from '@tinkoff/dippy';
|
|
3
|
-
import { provide, commandLineListTokens } from '@tramvai/core';
|
|
4
|
-
import { ENV_USED_TOKEN, LOGGER_TOKEN,
|
|
3
|
+
import { provide, TAPABLE_HOOK_FACTORY_TOKEN, commandLineListTokens } from '@tramvai/core';
|
|
4
|
+
import { ENV_USED_TOKEN, LOGGER_TOKEN, ENV_MANAGER_TOKEN, STORE_TOKEN, ASYNC_LOCAL_STORAGE_TOKEN } from '@tramvai/tokens-common';
|
|
5
5
|
import { RESOURCES_REGISTRY, RENDER_SLOTS, ResourceType, ResourceSlot, RENDER_FLOW_AFTER_TOKEN, REACT_SERVER_RENDER_MODE, EXTEND_RENDER } from '@tramvai/tokens-render';
|
|
6
|
-
import { CHILD_APP_LOADER_TOKEN, CHILD_APP_STATE_MANAGER_TOKEN, CHILD_APP_DI_MANAGER_TOKEN, CHILD_APP_PRELOAD_MANAGER_TOKEN, CHILD_APP_COMMAND_LINE_RUNNER_TOKEN, CHILD_APP_RESOLUTION_CONFIG_MANAGER_TOKEN, CHILD_APP_RESOLVE_CONFIG_TOKEN, CHILD_APP_RENDER_MANAGER_TOKEN, CHILD_APP_CONTRACT_MANAGER, HOST_PROVIDED_CONTRACTS, HOST_REQUIRED_CONTRACTS } from '@tramvai/tokens-child-app';
|
|
6
|
+
import { CHILD_APP_LOADER_TOKEN, CHILD_APP_LOADER_PLUGIN, CHILD_APP_LOADER_CACHE_TOKEN, CHILD_APP_STATE_MANAGER_TOKEN, CHILD_APP_DI_MANAGER_TOKEN, CHILD_APP_PRELOAD_MANAGER_TOKEN, CHILD_APP_PRELOAD_MANAGER_PLUGIN, CHILD_APP_COMMAND_LINE_RUNNER_TOKEN, CHILD_APP_RESOLUTION_CONFIG_MANAGER_TOKEN, CHILD_APP_RESOLVE_CONFIG_TOKEN, CHILD_APP_RENDER_MANAGER_TOKEN, CHILD_APP_CONTRACT_MANAGER, HOST_PROVIDED_CONTRACTS, HOST_REQUIRED_CONTRACTS } from '@tramvai/tokens-child-app';
|
|
7
7
|
import { safeStringify } from '@tramvai/safe-strings';
|
|
8
8
|
import { ServerLoader } from './loader.es.js';
|
|
9
9
|
import { PreloadManager } from './preload.es.js';
|
|
@@ -13,8 +13,10 @@ import { RenderManager } from './render.es.js';
|
|
|
13
13
|
import { registerChildAppRenderSlots } from './render-slots.es.js';
|
|
14
14
|
import { GLOBAL_CHILD_STATE } from '../shared/constants.es.js';
|
|
15
15
|
import { ChildAppContractManager } from '../contracts/contractManager.server.es.js';
|
|
16
|
+
import { cache } from './cache/cache.es.js';
|
|
16
17
|
|
|
17
18
|
const serverProviders = [
|
|
19
|
+
...cache,
|
|
18
20
|
provide({
|
|
19
21
|
provide: ENV_USED_TOKEN,
|
|
20
22
|
multi: true,
|
|
@@ -31,8 +33,13 @@ const serverProviders = [
|
|
|
31
33
|
useClass: ServerLoader,
|
|
32
34
|
scope: Scope.SINGLETON,
|
|
33
35
|
deps: {
|
|
36
|
+
plugins: {
|
|
37
|
+
optional: true,
|
|
38
|
+
token: CHILD_APP_LOADER_PLUGIN,
|
|
39
|
+
},
|
|
40
|
+
hookFactory: TAPABLE_HOOK_FACTORY_TOKEN,
|
|
34
41
|
logger: LOGGER_TOKEN,
|
|
35
|
-
|
|
42
|
+
cache: CHILD_APP_LOADER_CACHE_TOKEN,
|
|
36
43
|
envManager: ENV_MANAGER_TOKEN,
|
|
37
44
|
},
|
|
38
45
|
}),
|
|
@@ -49,6 +56,11 @@ const serverProviders = [
|
|
|
49
56
|
provide: CHILD_APP_PRELOAD_MANAGER_TOKEN,
|
|
50
57
|
useClass: PreloadManager,
|
|
51
58
|
deps: {
|
|
59
|
+
hookFactory: TAPABLE_HOOK_FACTORY_TOKEN,
|
|
60
|
+
plugins: {
|
|
61
|
+
optional: true,
|
|
62
|
+
token: CHILD_APP_PRELOAD_MANAGER_PLUGIN,
|
|
63
|
+
},
|
|
52
64
|
loader: CHILD_APP_LOADER_TOKEN,
|
|
53
65
|
runner: CHILD_APP_COMMAND_LINE_RUNNER_TOKEN,
|
|
54
66
|
stateManager: CHILD_APP_STATE_MANAGER_TOKEN,
|
|
@@ -102,6 +114,7 @@ const serverProviders = [
|
|
|
102
114
|
provide: CHILD_APP_RENDER_MANAGER_TOKEN,
|
|
103
115
|
useClass: RenderManager,
|
|
104
116
|
deps: {
|
|
117
|
+
hookFactory: TAPABLE_HOOK_FACTORY_TOKEN,
|
|
105
118
|
logger: LOGGER_TOKEN,
|
|
106
119
|
diManager: CHILD_APP_DI_MANAGER_TOKEN,
|
|
107
120
|
preloadManager: CHILD_APP_PRELOAD_MANAGER_TOKEN,
|
package/lib/server/providers.js
CHANGED
|
@@ -17,8 +17,10 @@ var render = require('./render.js');
|
|
|
17
17
|
var renderSlots = require('./render-slots.js');
|
|
18
18
|
var constants = require('../shared/constants.js');
|
|
19
19
|
var contractManager_server = require('../contracts/contractManager.server.js');
|
|
20
|
+
var cache = require('./cache/cache.js');
|
|
20
21
|
|
|
21
22
|
const serverProviders = [
|
|
23
|
+
...cache.cache,
|
|
22
24
|
core.provide({
|
|
23
25
|
provide: tokensCommon.ENV_USED_TOKEN,
|
|
24
26
|
multi: true,
|
|
@@ -35,8 +37,13 @@ const serverProviders = [
|
|
|
35
37
|
useClass: loader.ServerLoader,
|
|
36
38
|
scope: dippy.Scope.SINGLETON,
|
|
37
39
|
deps: {
|
|
40
|
+
plugins: {
|
|
41
|
+
optional: true,
|
|
42
|
+
token: tokensChildApp.CHILD_APP_LOADER_PLUGIN,
|
|
43
|
+
},
|
|
44
|
+
hookFactory: core.TAPABLE_HOOK_FACTORY_TOKEN,
|
|
38
45
|
logger: tokensCommon.LOGGER_TOKEN,
|
|
39
|
-
|
|
46
|
+
cache: tokensChildApp.CHILD_APP_LOADER_CACHE_TOKEN,
|
|
40
47
|
envManager: tokensCommon.ENV_MANAGER_TOKEN,
|
|
41
48
|
},
|
|
42
49
|
}),
|
|
@@ -53,6 +60,11 @@ const serverProviders = [
|
|
|
53
60
|
provide: tokensChildApp.CHILD_APP_PRELOAD_MANAGER_TOKEN,
|
|
54
61
|
useClass: preload.PreloadManager,
|
|
55
62
|
deps: {
|
|
63
|
+
hookFactory: core.TAPABLE_HOOK_FACTORY_TOKEN,
|
|
64
|
+
plugins: {
|
|
65
|
+
optional: true,
|
|
66
|
+
token: tokensChildApp.CHILD_APP_PRELOAD_MANAGER_PLUGIN,
|
|
67
|
+
},
|
|
56
68
|
loader: tokensChildApp.CHILD_APP_LOADER_TOKEN,
|
|
57
69
|
runner: tokensChildApp.CHILD_APP_COMMAND_LINE_RUNNER_TOKEN,
|
|
58
70
|
stateManager: tokensChildApp.CHILD_APP_STATE_MANAGER_TOKEN,
|
|
@@ -106,6 +118,7 @@ const serverProviders = [
|
|
|
106
118
|
provide: tokensChildApp.CHILD_APP_RENDER_MANAGER_TOKEN,
|
|
107
119
|
useClass: render.RenderManager,
|
|
108
120
|
deps: {
|
|
121
|
+
hookFactory: core.TAPABLE_HOOK_FACTORY_TOKEN,
|
|
109
122
|
logger: tokensCommon.LOGGER_TOKEN,
|
|
110
123
|
diManager: tokensChildApp.CHILD_APP_DI_MANAGER_TOKEN,
|
|
111
124
|
preloadManager: tokensChildApp.CHILD_APP_PRELOAD_MANAGER_TOKEN,
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { extname } from 'path';
|
|
2
|
-
import { gt, eq } from 'semver';
|
|
3
2
|
import flatten from '@tinkoff/utils/array/flatten';
|
|
4
3
|
import { resolve } from '@tinkoff/url';
|
|
5
4
|
import { CHILD_APP_INTERNAL_CHUNK_EXTRACTOR } from '@tramvai/tokens-child-app';
|
|
6
5
|
import { RENDER_SLOTS, ResourceType, ResourceSlot } from '@tramvai/tokens-render';
|
|
7
6
|
import { getSharedScope } from '../shared/webpack/moduleFederation.es.js';
|
|
7
|
+
import { getFlatSharedScopeItemsList, getFlatSharedModulesList } from './module-federation/utils.es.js';
|
|
8
|
+
import { resolveBestLoadedSharedModules } from './module-federation/best-loaded-shared-modules.es.js';
|
|
8
9
|
|
|
9
10
|
const asyncScriptAttrs = {
|
|
10
11
|
defer: null,
|
|
@@ -18,14 +19,16 @@ const deferScriptAttrs = {
|
|
|
18
19
|
// and Child App initialization logic executed after that, we need to get script loading status
|
|
19
20
|
const entryAttrs = {
|
|
20
21
|
onload: `this.setAttribute('loaded', 'true')`,
|
|
21
|
-
onerror: `this.setAttribute('loaded', '
|
|
22
|
+
onerror: `this.setAttribute('loaded', 'error')`,
|
|
22
23
|
};
|
|
23
24
|
// for cases when preloaded chunk loading is failed before webpack add this script loading handlers,
|
|
24
25
|
// we need to remove script and webpack will try to load it itself https://github.com/webpack/webpack/issues/14874
|
|
25
26
|
const chunkAttrs = {
|
|
26
27
|
onerror: `this.remove()`,
|
|
27
28
|
};
|
|
28
|
-
const registerChildAppRenderSlots = ({ logger, diManager, resolveFullConfig, preloadManager, loader, renderMode, resourcesRegistry, }) =>
|
|
29
|
+
const registerChildAppRenderSlots = ({ logger, diManager, resolveFullConfig, preloadManager, loader, renderMode, resourcesRegistry, }) =>
|
|
30
|
+
// eslint-disable-next-line max-statements
|
|
31
|
+
async () => {
|
|
29
32
|
const log = logger('child-app:render:slots');
|
|
30
33
|
const result = [];
|
|
31
34
|
// defer scripts is not suitable for React streaming, we need to ability to run them as early as possible
|
|
@@ -64,36 +67,25 @@ const registerChildAppRenderSlots = ({ logger, diManager, resolveFullConfig, pre
|
|
|
64
67
|
};
|
|
65
68
|
const preloadedList = new Set(preloadManager.getPreloadedList());
|
|
66
69
|
const sharedScope = getSharedScope();
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
//
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
// if versions are equal then module federation will pick
|
|
85
|
-
// the dep with eager prop (it's set in root-app) of with the child-app with highest name in alphabetical order
|
|
86
|
-
(eq(version, last.version) && (eager !== last.eager ? eager : name > last.name))) {
|
|
87
|
-
mapSharedToChildApp.set(shareKey, { version, type, name, eager });
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
70
|
+
const preloadedConfigs = Array.from(preloadedList)
|
|
71
|
+
.map((requestConfig) => {
|
|
72
|
+
return resolveFullConfig(requestConfig);
|
|
73
|
+
})
|
|
74
|
+
.filter(Boolean);
|
|
75
|
+
// flat list of all shared items initialized in shared scope
|
|
76
|
+
const sharedScopeItems = getFlatSharedScopeItemsList(sharedScope);
|
|
77
|
+
// flat list of all preloaded Child Apps shared modules
|
|
78
|
+
const sharedModules = getFlatSharedModulesList({
|
|
79
|
+
preloadedConfigs,
|
|
80
|
+
loader: loader,
|
|
81
|
+
});
|
|
82
|
+
// optimal shared dependencies for preloaded Child Apps
|
|
83
|
+
const bestSharedModules = resolveBestLoadedSharedModules({
|
|
84
|
+
sharedModules,
|
|
85
|
+
sharedScopeItems,
|
|
86
|
+
});
|
|
91
87
|
// eslint-disable-next-line max-statements
|
|
92
|
-
|
|
93
|
-
const config = resolveFullConfig(requestConfig);
|
|
94
|
-
if (!config) {
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
88
|
+
preloadedConfigs.forEach((config) => {
|
|
97
89
|
const stats = 'getStats' in loader ? loader.getStats(config) : undefined;
|
|
98
90
|
const di = diManager.getChildDi(config);
|
|
99
91
|
const loadableAssets = di?.get(CHILD_APP_INTERNAL_CHUNK_EXTRACTOR)?.getMainAssets();
|
|
@@ -123,21 +115,6 @@ const registerChildAppRenderSlots = ({ logger, diManager, resolveFullConfig, pre
|
|
|
123
115
|
for (const file of files) {
|
|
124
116
|
addChunk(resolve(config.client.baseUrl, file));
|
|
125
117
|
}
|
|
126
|
-
for (const sharedModule of federatedModule.sharedModules) {
|
|
127
|
-
const { shareKey } = sharedModule.provides?.[0] ?? {};
|
|
128
|
-
const { chunks } = sharedModule;
|
|
129
|
-
const bestShared = mapSharedToChildApp.get(shareKey);
|
|
130
|
-
if (!bestShared?.eager && bestShared?.name === config.name) {
|
|
131
|
-
for (const chunk of chunks) {
|
|
132
|
-
addChunk(resolve(config.client.baseUrl, chunk));
|
|
133
|
-
}
|
|
134
|
-
// in stats.json federated stats could contain 2 sets of chunks for shared modules
|
|
135
|
-
// there usual one and fallback. For shared module there could be used any of this
|
|
136
|
-
// and the other one will be useless. So delete entry from map after its usage in order
|
|
137
|
-
// to add only single set of chunks for the same shared dep
|
|
138
|
-
mapSharedToChildApp.delete(shareKey);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
118
|
}
|
|
142
119
|
}
|
|
143
120
|
if (!di) {
|
|
@@ -153,13 +130,48 @@ const registerChildAppRenderSlots = ({ logger, diManager, resolveFullConfig, pre
|
|
|
153
130
|
log.error({
|
|
154
131
|
event: 'get-slots-failed',
|
|
155
132
|
childApp: {
|
|
156
|
-
name:
|
|
157
|
-
version:
|
|
158
|
-
tag:
|
|
133
|
+
name: config.name,
|
|
134
|
+
version: config.version,
|
|
135
|
+
tag: config.tag,
|
|
159
136
|
},
|
|
160
137
|
});
|
|
161
138
|
}
|
|
162
139
|
});
|
|
140
|
+
// shared chunks deduplication
|
|
141
|
+
const addedSharedChunks = new Set();
|
|
142
|
+
// preloaded chunks we need to pass to client
|
|
143
|
+
const serializableSharedModules = [];
|
|
144
|
+
bestSharedModules.forEach(({ shareKey, version, chunks, childAppName, childAppVersion }) => {
|
|
145
|
+
const childAppConfig = preloadedConfigs.find((config) => {
|
|
146
|
+
return config.name === childAppName && config.version === childAppVersion;
|
|
147
|
+
});
|
|
148
|
+
// if it is application shared dependency, we don't have any extra chunks
|
|
149
|
+
if (childAppConfig && chunks) {
|
|
150
|
+
for (const chunk of chunks) {
|
|
151
|
+
if (!addedSharedChunks.has(chunk)) {
|
|
152
|
+
addedSharedChunks.add(chunk);
|
|
153
|
+
addChunk(resolve(childAppConfig.client.baseUrl, chunk));
|
|
154
|
+
const containerName = `child-app__${childAppConfig.client.entry}`;
|
|
155
|
+
serializableSharedModules.push({
|
|
156
|
+
containerName,
|
|
157
|
+
shareKey,
|
|
158
|
+
version,
|
|
159
|
+
childAppName: childAppName,
|
|
160
|
+
childAppVersion: childAppVersion,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
result.push({
|
|
167
|
+
type: ResourceType.inlineScript,
|
|
168
|
+
slot: ResourceSlot.HEAD_POLYFILLS,
|
|
169
|
+
payload: `window.__webpack_share_preloaded__ = [
|
|
170
|
+
${serializableSharedModules.map((m) => {
|
|
171
|
+
return `${JSON.stringify(m)}`;
|
|
172
|
+
})}
|
|
173
|
+
];`,
|
|
174
|
+
});
|
|
163
175
|
result.map((item) => resourcesRegistry.register(item));
|
|
164
176
|
};
|
|
165
177
|
|