@module-federation/runtime 0.8.6 → 0.8.8

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.
Files changed (55) hide show
  1. package/dist/core.cjs.d.ts +2 -0
  2. package/dist/core.cjs.js +15 -0
  3. package/dist/core.esm.d.ts +2 -0
  4. package/dist/core.esm.mjs +3 -0
  5. package/dist/helpers.cjs.js +7 -27
  6. package/dist/helpers.esm.mjs +7 -27
  7. package/dist/index.cjs.js +34 -2086
  8. package/dist/index.esm.mjs +4 -2072
  9. package/dist/polyfills.cjs.js +0 -14
  10. package/dist/polyfills.esm.mjs +1 -14
  11. package/dist/src/core.d.ts +3 -114
  12. package/dist/src/embedded.d.ts +49 -49
  13. package/dist/src/helpers.d.ts +23 -29
  14. package/dist/src/index.d.ts +3 -9
  15. package/dist/src/types.d.ts +1 -1
  16. package/dist/src/utils.d.ts +3 -0
  17. package/dist/types.cjs.js +10 -0
  18. package/dist/types.esm.mjs +1 -1
  19. package/dist/utils.cjs.js +26 -0
  20. package/dist/utils.esm.mjs +24 -0
  21. package/package.json +12 -3
  22. package/dist/share.cjs.js +0 -937
  23. package/dist/share.esm.mjs +0 -896
  24. package/dist/src/constant.d.ts +0 -2
  25. package/dist/src/global.d.ts +0 -43
  26. package/dist/src/module/index.d.ts +0 -21
  27. package/dist/src/plugins/generate-preload-assets.d.ts +0 -8
  28. package/dist/src/plugins/snapshot/SnapshotHandler.d.ts +0 -58
  29. package/dist/src/plugins/snapshot/index.d.ts +0 -5
  30. package/dist/src/remote/index.d.ts +0 -109
  31. package/dist/src/shared/index.d.ts +0 -66
  32. package/dist/src/type/config.d.ts +0 -112
  33. package/dist/src/type/index.d.ts +0 -3
  34. package/dist/src/type/plugin.d.ts +0 -34
  35. package/dist/src/type/preload.d.ts +0 -26
  36. package/dist/src/utils/env.d.ts +0 -3
  37. package/dist/src/utils/hooks/asyncHook.d.ts +0 -6
  38. package/dist/src/utils/hooks/asyncWaterfallHooks.d.ts +0 -10
  39. package/dist/src/utils/hooks/index.d.ts +0 -6
  40. package/dist/src/utils/hooks/pluginSystem.d.ts +0 -15
  41. package/dist/src/utils/hooks/syncHook.d.ts +0 -12
  42. package/dist/src/utils/hooks/syncWaterfallHook.d.ts +0 -9
  43. package/dist/src/utils/index.d.ts +0 -6
  44. package/dist/src/utils/load.d.ts +0 -9
  45. package/dist/src/utils/logger.d.ts +0 -6
  46. package/dist/src/utils/manifest.d.ts +0 -7
  47. package/dist/src/utils/plugin.d.ts +0 -4
  48. package/dist/src/utils/preload.d.ts +0 -6
  49. package/dist/src/utils/semver/compare.d.ts +0 -9
  50. package/dist/src/utils/semver/constants.d.ts +0 -10
  51. package/dist/src/utils/semver/index.d.ts +0 -2
  52. package/dist/src/utils/semver/parser.d.ts +0 -9
  53. package/dist/src/utils/semver/utils.d.ts +0 -11
  54. package/dist/src/utils/share.d.ts +0 -27
  55. package/dist/src/utils/tool.d.ts +0 -18
package/dist/index.cjs.js CHANGED
@@ -1,2084 +1,17 @@
1
1
  'use strict';
2
2
 
3
- var polyfills = require('./polyfills.cjs.js');
4
- var sdk = require('@module-federation/sdk');
5
- var share = require('./share.cjs.js');
6
- var errorCodes = require('@module-federation/error-codes');
7
-
8
- // Function to match a remote with its name and expose
9
- // id: pkgName(@federation/app1) + expose(button) = @federation/app1/button
10
- // id: alias(app1) + expose(button) = app1/button
11
- // id: alias(app1/utils) + expose(loadash/sort) = app1/utils/loadash/sort
12
- function matchRemoteWithNameAndExpose(remotes, id) {
13
- for (const remote of remotes){
14
- // match pkgName
15
- const isNameMatched = id.startsWith(remote.name);
16
- let expose = id.replace(remote.name, '');
17
- if (isNameMatched) {
18
- if (expose.startsWith('/')) {
19
- const pkgNameOrAlias = remote.name;
20
- expose = `.${expose}`;
21
- return {
22
- pkgNameOrAlias,
23
- expose,
24
- remote
25
- };
26
- } else if (expose === '') {
27
- return {
28
- pkgNameOrAlias: remote.name,
29
- expose: '.',
30
- remote
31
- };
32
- }
33
- }
34
- // match alias
35
- const isAliasMatched = remote.alias && id.startsWith(remote.alias);
36
- let exposeWithAlias = remote.alias && id.replace(remote.alias, '');
37
- if (remote.alias && isAliasMatched) {
38
- if (exposeWithAlias && exposeWithAlias.startsWith('/')) {
39
- const pkgNameOrAlias = remote.alias;
40
- exposeWithAlias = `.${exposeWithAlias}`;
41
- return {
42
- pkgNameOrAlias,
43
- expose: exposeWithAlias,
44
- remote
45
- };
46
- } else if (exposeWithAlias === '') {
47
- return {
48
- pkgNameOrAlias: remote.alias,
49
- expose: '.',
50
- remote
51
- };
52
- }
53
- }
54
- }
55
- return;
56
- }
57
- // Function to match a remote with its name or alias
58
- function matchRemote(remotes, nameOrAlias) {
59
- for (const remote of remotes){
60
- const isNameMatched = nameOrAlias === remote.name;
61
- if (isNameMatched) {
62
- return remote;
63
- }
64
- const isAliasMatched = remote.alias && nameOrAlias === remote.alias;
65
- if (isAliasMatched) {
66
- return remote;
67
- }
68
- }
69
- return;
70
- }
71
-
72
- function registerPlugins$1(plugins, hookInstances) {
73
- const globalPlugins = share.getGlobalHostPlugins();
74
- // Incorporate global plugins
75
- if (globalPlugins.length > 0) {
76
- globalPlugins.forEach((plugin)=>{
77
- if (plugins == null ? void 0 : plugins.find((item)=>item.name !== plugin.name)) {
78
- plugins.push(plugin);
79
- }
80
- });
81
- }
82
- if (plugins && plugins.length > 0) {
83
- plugins.forEach((plugin)=>{
84
- hookInstances.forEach((hookInstance)=>{
85
- hookInstance.applyPlugin(plugin);
86
- });
87
- });
88
- }
89
- return plugins;
90
- }
91
-
92
- async function loadEsmEntry({ entry, remoteEntryExports }) {
93
- return new Promise((resolve, reject)=>{
94
- try {
95
- if (!remoteEntryExports) {
96
- if (typeof FEDERATION_ALLOW_NEW_FUNCTION !== 'undefined') {
97
- new Function('callbacks', `import("${entry}").then(callbacks[0]).catch(callbacks[1])`)([
98
- resolve,
99
- reject
100
- ]);
101
- } else {
102
- import(/* webpackIgnore: true */ /* @vite-ignore */ entry).then(resolve).catch(reject);
103
- }
104
- } else {
105
- resolve(remoteEntryExports);
106
- }
107
- } catch (e) {
108
- reject(e);
109
- }
110
- });
111
- }
112
- async function loadSystemJsEntry({ entry, remoteEntryExports }) {
113
- return new Promise((resolve, reject)=>{
114
- try {
115
- if (!remoteEntryExports) {
116
- //@ts-ignore
117
- if (typeof __system_context__ === 'undefined') {
118
- //@ts-ignore
119
- System.import(entry).then(resolve).catch(reject);
120
- } else {
121
- new Function('callbacks', `System.import("${entry}").then(callbacks[0]).catch(callbacks[1])`)([
122
- resolve,
123
- reject
124
- ]);
125
- }
126
- } else {
127
- resolve(remoteEntryExports);
128
- }
129
- } catch (e) {
130
- reject(e);
131
- }
132
- });
133
- }
134
- async function loadEntryScript({ name, globalName, entry, loaderHook }) {
135
- const { entryExports: remoteEntryExports } = share.getRemoteEntryExports(name, globalName);
136
- if (remoteEntryExports) {
137
- return remoteEntryExports;
138
- }
139
- return sdk.loadScript(entry, {
140
- attrs: {},
141
- createScriptHook: (url, attrs)=>{
142
- const res = loaderHook.lifecycle.createScript.emit({
143
- url,
144
- attrs
145
- });
146
- if (!res) return;
147
- if (res instanceof HTMLScriptElement) {
148
- return res;
149
- }
150
- if ('script' in res || 'timeout' in res) {
151
- return res;
152
- }
153
- return;
154
- }
155
- }).then(()=>{
156
- const { remoteEntryKey, entryExports } = share.getRemoteEntryExports(name, globalName);
157
- share.assert(entryExports, errorCodes.getShortErrorMsg(errorCodes.RUNTIME_001, errorCodes.runtimeDescMap, {
158
- remoteName: name,
159
- remoteEntryUrl: entry,
160
- remoteEntryKey
161
- }));
162
- return entryExports;
163
- }).catch((e)=>{
164
- throw e;
165
- });
166
- }
167
- async function loadEntryDom({ remoteInfo, remoteEntryExports, loaderHook }) {
168
- const { entry, entryGlobalName: globalName, name, type } = remoteInfo;
169
- switch(type){
170
- case 'esm':
171
- case 'module':
172
- return loadEsmEntry({
173
- entry,
174
- remoteEntryExports
175
- });
176
- case 'system':
177
- return loadSystemJsEntry({
178
- entry,
179
- remoteEntryExports
180
- });
181
- default:
182
- return loadEntryScript({
183
- entry,
184
- globalName,
185
- name,
186
- loaderHook
187
- });
188
- }
189
- }
190
- async function loadEntryNode({ remoteInfo, loaderHook }) {
191
- const { entry, entryGlobalName: globalName, name, type } = remoteInfo;
192
- const { entryExports: remoteEntryExports } = share.getRemoteEntryExports(name, globalName);
193
- if (remoteEntryExports) {
194
- return remoteEntryExports;
195
- }
196
- return sdk.loadScriptNode(entry, {
197
- attrs: {
198
- name,
199
- globalName,
200
- type
201
- },
202
- loaderHook: {
203
- createScriptHook: (url, attrs = {})=>{
204
- const res = loaderHook.lifecycle.createScript.emit({
205
- url,
206
- attrs
207
- });
208
- if (!res) return;
209
- if ('url' in res) {
210
- return res;
211
- }
212
- return;
213
- }
214
- }
215
- }).then(()=>{
216
- const { remoteEntryKey, entryExports } = share.getRemoteEntryExports(name, globalName);
217
- share.assert(entryExports, errorCodes.getShortErrorMsg(errorCodes.RUNTIME_001, errorCodes.runtimeDescMap, {
218
- remoteName: name,
219
- remoteEntryUrl: entry,
220
- remoteEntryKey
221
- }));
222
- return entryExports;
223
- }).catch((e)=>{
224
- throw e;
225
- });
226
- }
227
- function getRemoteEntryUniqueKey(remoteInfo) {
228
- const { entry, name } = remoteInfo;
229
- return sdk.composeKeyWithSeparator(name, entry);
230
- }
231
- async function getRemoteEntry({ origin, remoteEntryExports, remoteInfo }) {
232
- const uniqueKey = getRemoteEntryUniqueKey(remoteInfo);
233
- if (remoteEntryExports) {
234
- return remoteEntryExports;
235
- }
236
- if (!share.globalLoading[uniqueKey]) {
237
- const loadEntryHook = origin.remoteHandler.hooks.lifecycle.loadEntry;
238
- const loaderHook = origin.loaderHook;
239
- share.globalLoading[uniqueKey] = loadEntryHook.emit({
240
- loaderHook,
241
- remoteInfo,
242
- remoteEntryExports
243
- }).then((res)=>{
244
- if (res) {
245
- return res;
246
- }
247
- return sdk.isBrowserEnv() ? loadEntryDom({
248
- remoteInfo,
249
- remoteEntryExports,
250
- loaderHook
251
- }) : loadEntryNode({
252
- remoteInfo,
253
- loaderHook
254
- });
255
- });
256
- }
257
- return share.globalLoading[uniqueKey];
258
- }
259
- function getRemoteInfo(remote) {
260
- return polyfills._extends({}, remote, {
261
- entry: 'entry' in remote ? remote.entry : '',
262
- type: remote.type || share.DEFAULT_REMOTE_TYPE,
263
- entryGlobalName: remote.entryGlobalName || remote.name,
264
- shareScope: remote.shareScope || share.DEFAULT_SCOPE
265
- });
266
- }
267
-
268
- let Module = class Module {
269
- async getEntry() {
270
- if (this.remoteEntryExports) {
271
- return this.remoteEntryExports;
272
- }
273
- let remoteEntryExports;
274
- try {
275
- remoteEntryExports = await getRemoteEntry({
276
- origin: this.host,
277
- remoteInfo: this.remoteInfo,
278
- remoteEntryExports: this.remoteEntryExports
279
- });
280
- } catch (err) {
281
- const uniqueKey = getRemoteEntryUniqueKey(this.remoteInfo);
282
- remoteEntryExports = await this.host.loaderHook.lifecycle.loadEntryError.emit({
283
- getRemoteEntry,
284
- origin: this.host,
285
- remoteInfo: this.remoteInfo,
286
- remoteEntryExports: this.remoteEntryExports,
287
- globalLoading: share.globalLoading,
288
- uniqueKey
289
- });
290
- }
291
- share.assert(remoteEntryExports, `remoteEntryExports is undefined \n ${sdk.safeToString(this.remoteInfo)}`);
292
- this.remoteEntryExports = remoteEntryExports;
293
- return this.remoteEntryExports;
294
- }
295
- // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
296
- async get(id, expose, options, remoteSnapshot) {
297
- const { loadFactory = true } = options || {
298
- loadFactory: true
299
- };
300
- // Get remoteEntry.js
301
- const remoteEntryExports = await this.getEntry();
302
- if (!this.inited) {
303
- const localShareScopeMap = this.host.shareScopeMap;
304
- const remoteShareScope = this.remoteInfo.shareScope || 'default';
305
- if (!localShareScopeMap[remoteShareScope]) {
306
- localShareScopeMap[remoteShareScope] = {};
307
- }
308
- const shareScope = localShareScopeMap[remoteShareScope];
309
- const initScope = [];
310
- const remoteEntryInitOptions = {
311
- version: this.remoteInfo.version || ''
312
- };
313
- // Help to find host instance
314
- Object.defineProperty(remoteEntryInitOptions, 'shareScopeMap', {
315
- value: localShareScopeMap,
316
- // remoteEntryInitOptions will be traversed and assigned during container init, ,so this attribute is not allowed to be traversed
317
- enumerable: false
318
- });
319
- const initContainerOptions = await this.host.hooks.lifecycle.beforeInitContainer.emit({
320
- shareScope,
321
- // @ts-ignore shareScopeMap will be set by Object.defineProperty
322
- remoteEntryInitOptions,
323
- initScope,
324
- remoteInfo: this.remoteInfo,
325
- origin: this.host
326
- });
327
- if (typeof (remoteEntryExports == null ? void 0 : remoteEntryExports.init) === 'undefined') {
328
- share.error(errorCodes.getShortErrorMsg(errorCodes.RUNTIME_002, errorCodes.runtimeDescMap, {
329
- remoteName: name,
330
- remoteEntryUrl: this.remoteInfo.entry,
331
- remoteEntryKey: this.remoteInfo.entryGlobalName
332
- }));
333
- }
334
- await remoteEntryExports.init(initContainerOptions.shareScope, initContainerOptions.initScope, initContainerOptions.remoteEntryInitOptions);
335
- await this.host.hooks.lifecycle.initContainer.emit(polyfills._extends({}, initContainerOptions, {
336
- id,
337
- remoteSnapshot,
338
- remoteEntryExports
339
- }));
340
- }
341
- this.lib = remoteEntryExports;
342
- this.inited = true;
343
- let moduleFactory;
344
- moduleFactory = await this.host.loaderHook.lifecycle.getModuleFactory.emit({
345
- remoteEntryExports,
346
- expose,
347
- moduleInfo: this.remoteInfo
348
- });
349
- // get exposeGetter
350
- if (!moduleFactory) {
351
- moduleFactory = await remoteEntryExports.get(expose);
352
- }
353
- share.assert(moduleFactory, `${share.getFMId(this.remoteInfo)} remote don't export ${expose}.`);
354
- // keep symbol for module name always one format
355
- const symbolName = share.processModuleAlias(this.remoteInfo.name, expose);
356
- const wrapModuleFactory = this.wraperFactory(moduleFactory, symbolName);
357
- if (!loadFactory) {
358
- return wrapModuleFactory;
359
- }
360
- const exposeContent = await wrapModuleFactory();
361
- return exposeContent;
362
- }
363
- wraperFactory(moduleFactory, id) {
364
- function defineModuleId(res, id) {
365
- if (res && typeof res === 'object' && Object.isExtensible(res) && !Object.getOwnPropertyDescriptor(res, Symbol.for('mf_module_id'))) {
366
- Object.defineProperty(res, Symbol.for('mf_module_id'), {
367
- value: id,
368
- enumerable: false
369
- });
370
- }
371
- }
372
- if (moduleFactory instanceof Promise) {
373
- return async ()=>{
374
- const res = await moduleFactory();
375
- // This parameter is used for bridge debugging
376
- defineModuleId(res, id);
377
- return res;
378
- };
379
- } else {
380
- return ()=>{
381
- const res = moduleFactory();
382
- // This parameter is used for bridge debugging
383
- defineModuleId(res, id);
384
- return res;
385
- };
386
- }
387
- }
388
- constructor({ remoteInfo, host }){
389
- this.inited = false;
390
- this.lib = undefined;
391
- this.remoteInfo = remoteInfo;
392
- this.host = host;
393
- }
394
- };
395
-
396
- class SyncHook {
397
- on(fn) {
398
- if (typeof fn === 'function') {
399
- this.listeners.add(fn);
400
- }
401
- }
402
- once(fn) {
403
- // eslint-disable-next-line @typescript-eslint/no-this-alias
404
- const self = this;
405
- this.on(function wrapper(...args) {
406
- self.remove(wrapper);
407
- // eslint-disable-next-line prefer-spread
408
- return fn.apply(null, args);
409
- });
410
- }
411
- emit(...data) {
412
- let result;
413
- if (this.listeners.size > 0) {
414
- // eslint-disable-next-line prefer-spread
415
- this.listeners.forEach((fn)=>{
416
- result = fn(...data);
417
- });
418
- }
419
- return result;
420
- }
421
- remove(fn) {
422
- this.listeners.delete(fn);
423
- }
424
- removeAll() {
425
- this.listeners.clear();
426
- }
427
- constructor(type){
428
- this.type = '';
429
- this.listeners = new Set();
430
- if (type) {
431
- this.type = type;
432
- }
433
- }
434
- }
435
-
436
- class AsyncHook extends SyncHook {
437
- emit(...data) {
438
- let result;
439
- const ls = Array.from(this.listeners);
440
- if (ls.length > 0) {
441
- let i = 0;
442
- const call = (prev)=>{
443
- if (prev === false) {
444
- return false; // Abort process
445
- } else if (i < ls.length) {
446
- return Promise.resolve(ls[i++].apply(null, data)).then(call);
447
- } else {
448
- return prev;
449
- }
450
- };
451
- result = call();
452
- }
453
- return Promise.resolve(result);
454
- }
455
- }
456
-
457
- // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
458
- function checkReturnData(originalData, returnedData) {
459
- if (!share.isObject(returnedData)) {
460
- return false;
461
- }
462
- if (originalData !== returnedData) {
463
- // eslint-disable-next-line no-restricted-syntax
464
- for(const key in originalData){
465
- if (!(key in returnedData)) {
466
- return false;
467
- }
468
- }
469
- }
470
- return true;
471
- }
472
- class SyncWaterfallHook extends SyncHook {
473
- emit(data) {
474
- if (!share.isObject(data)) {
475
- share.error(`The data for the "${this.type}" hook should be an object.`);
476
- }
477
- for (const fn of this.listeners){
478
- try {
479
- const tempData = fn(data);
480
- if (checkReturnData(data, tempData)) {
481
- data = tempData;
482
- } else {
483
- this.onerror(`A plugin returned an unacceptable value for the "${this.type}" type.`);
484
- break;
485
- }
486
- } catch (e) {
487
- share.warn(e);
488
- this.onerror(e);
489
- }
490
- }
491
- return data;
492
- }
493
- constructor(type){
494
- super(), this.onerror = share.error;
495
- this.type = type;
496
- }
497
- }
498
-
499
- class AsyncWaterfallHook extends SyncHook {
500
- emit(data) {
501
- if (!share.isObject(data)) {
502
- share.error(`The response data for the "${this.type}" hook must be an object.`);
503
- }
504
- const ls = Array.from(this.listeners);
505
- if (ls.length > 0) {
506
- let i = 0;
507
- const processError = (e)=>{
508
- share.warn(e);
509
- this.onerror(e);
510
- return data;
511
- };
512
- const call = (prevData)=>{
513
- if (checkReturnData(data, prevData)) {
514
- data = prevData;
515
- if (i < ls.length) {
516
- try {
517
- return Promise.resolve(ls[i++](data)).then(call, processError);
518
- } catch (e) {
519
- return processError(e);
520
- }
521
- }
522
- } else {
523
- this.onerror(`A plugin returned an incorrect value for the "${this.type}" type.`);
524
- }
525
- return data;
526
- };
527
- return Promise.resolve(call(data));
528
- }
529
- return Promise.resolve(data);
530
- }
531
- constructor(type){
532
- super(), this.onerror = share.error;
533
- this.type = type;
534
- }
535
- }
536
-
537
- class PluginSystem {
538
- applyPlugin(plugin) {
539
- share.assert(share.isPlainObject(plugin), 'Plugin configuration is invalid.');
540
- // The plugin's name is mandatory and must be unique
541
- const pluginName = plugin.name;
542
- share.assert(pluginName, 'A name must be provided by the plugin.');
543
- if (!this.registerPlugins[pluginName]) {
544
- this.registerPlugins[pluginName] = plugin;
545
- Object.keys(this.lifecycle).forEach((key)=>{
546
- const pluginLife = plugin[key];
547
- if (pluginLife) {
548
- this.lifecycle[key].on(pluginLife);
549
- }
550
- });
551
- }
552
- }
553
- removePlugin(pluginName) {
554
- share.assert(pluginName, 'A name is required.');
555
- const plugin = this.registerPlugins[pluginName];
556
- share.assert(plugin, `The plugin "${pluginName}" is not registered.`);
557
- Object.keys(plugin).forEach((key)=>{
558
- if (key !== 'name') {
559
- this.lifecycle[key].remove(plugin[key]);
560
- }
561
- });
562
- }
563
- // eslint-disable-next-line @typescript-eslint/no-shadow
564
- inherit({ lifecycle, registerPlugins }) {
565
- Object.keys(lifecycle).forEach((hookName)=>{
566
- share.assert(!this.lifecycle[hookName], `The hook "${hookName}" has a conflict and cannot be inherited.`);
567
- this.lifecycle[hookName] = lifecycle[hookName];
568
- });
569
- Object.keys(registerPlugins).forEach((pluginName)=>{
570
- share.assert(!this.registerPlugins[pluginName], `The plugin "${pluginName}" has a conflict and cannot be inherited.`);
571
- this.applyPlugin(registerPlugins[pluginName]);
572
- });
573
- }
574
- constructor(lifecycle){
575
- this.registerPlugins = {};
576
- this.lifecycle = lifecycle;
577
- this.lifecycleKeys = Object.keys(lifecycle);
578
- }
579
- }
580
-
581
- function defaultPreloadArgs(preloadConfig) {
582
- return polyfills._extends({
583
- resourceCategory: 'sync',
584
- share: true,
585
- depsRemote: true,
586
- prefetchInterface: false
587
- }, preloadConfig);
588
- }
589
- function formatPreloadArgs(remotes, preloadArgs) {
590
- return preloadArgs.map((args)=>{
591
- const remoteInfo = matchRemote(remotes, args.nameOrAlias);
592
- share.assert(remoteInfo, `Unable to preload ${args.nameOrAlias} as it is not included in ${!remoteInfo && sdk.safeToString({
593
- remoteInfo,
594
- remotes
595
- })}`);
596
- return {
597
- remote: remoteInfo,
598
- preloadConfig: defaultPreloadArgs(args)
599
- };
600
- });
601
- }
602
- function normalizePreloadExposes(exposes) {
603
- if (!exposes) {
604
- return [];
605
- }
606
- return exposes.map((expose)=>{
607
- if (expose === '.') {
608
- return expose;
609
- }
610
- if (expose.startsWith('./')) {
611
- return expose.replace('./', '');
612
- }
613
- return expose;
614
- });
615
- }
616
- function preloadAssets(remoteInfo, host, assets, // It is used to distinguish preload from load remote parallel loading
617
- useLinkPreload = true) {
618
- const { cssAssets, jsAssetsWithoutEntry, entryAssets } = assets;
619
- if (host.options.inBrowser) {
620
- entryAssets.forEach((asset)=>{
621
- const { moduleInfo } = asset;
622
- const module = host.moduleCache.get(remoteInfo.name);
623
- if (module) {
624
- getRemoteEntry({
625
- origin: host,
626
- remoteInfo: moduleInfo,
627
- remoteEntryExports: module.remoteEntryExports
628
- });
629
- } else {
630
- getRemoteEntry({
631
- origin: host,
632
- remoteInfo: moduleInfo,
633
- remoteEntryExports: undefined
634
- });
635
- }
636
- });
637
- if (useLinkPreload) {
638
- const defaultAttrs = {
639
- rel: 'preload',
640
- as: 'style'
641
- };
642
- cssAssets.forEach((cssUrl)=>{
643
- const { link: cssEl, needAttach } = sdk.createLink({
644
- url: cssUrl,
645
- cb: ()=>{
646
- // noop
647
- },
648
- attrs: defaultAttrs,
649
- createLinkHook: (url, attrs)=>{
650
- const res = host.loaderHook.lifecycle.createLink.emit({
651
- url,
652
- attrs
653
- });
654
- if (res instanceof HTMLLinkElement) {
655
- return res;
656
- }
657
- return;
658
- }
659
- });
660
- needAttach && document.head.appendChild(cssEl);
661
- });
662
- } else {
663
- const defaultAttrs = {
664
- rel: 'stylesheet',
665
- type: 'text/css'
666
- };
667
- cssAssets.forEach((cssUrl)=>{
668
- const { link: cssEl, needAttach } = sdk.createLink({
669
- url: cssUrl,
670
- cb: ()=>{
671
- // noop
672
- },
673
- attrs: defaultAttrs,
674
- createLinkHook: (url, attrs)=>{
675
- const res = host.loaderHook.lifecycle.createLink.emit({
676
- url,
677
- attrs
678
- });
679
- if (res instanceof HTMLLinkElement) {
680
- return res;
681
- }
682
- return;
683
- },
684
- needDeleteLink: false
685
- });
686
- needAttach && document.head.appendChild(cssEl);
687
- });
688
- }
689
- if (useLinkPreload) {
690
- const defaultAttrs = {
691
- rel: 'preload',
692
- as: 'script'
693
- };
694
- jsAssetsWithoutEntry.forEach((jsUrl)=>{
695
- const { link: linkEl, needAttach } = sdk.createLink({
696
- url: jsUrl,
697
- cb: ()=>{
698
- // noop
699
- },
700
- attrs: defaultAttrs,
701
- createLinkHook: (url, attrs)=>{
702
- const res = host.loaderHook.lifecycle.createLink.emit({
703
- url,
704
- attrs
705
- });
706
- if (res instanceof HTMLLinkElement) {
707
- return res;
708
- }
709
- return;
710
- }
711
- });
712
- needAttach && document.head.appendChild(linkEl);
713
- });
714
- } else {
715
- const defaultAttrs = {
716
- fetchpriority: 'high',
717
- type: (remoteInfo == null ? void 0 : remoteInfo.type) === 'module' ? 'module' : 'text/javascript'
718
- };
719
- jsAssetsWithoutEntry.forEach((jsUrl)=>{
720
- const { script: scriptEl, needAttach } = sdk.createScript({
721
- url: jsUrl,
722
- cb: ()=>{
723
- // noop
724
- },
725
- attrs: defaultAttrs,
726
- createScriptHook: (url, attrs)=>{
727
- const res = host.loaderHook.lifecycle.createScript.emit({
728
- url,
729
- attrs
730
- });
731
- if (res instanceof HTMLScriptElement) {
732
- return res;
733
- }
734
- return;
735
- },
736
- needDeleteScript: true
737
- });
738
- needAttach && document.head.appendChild(scriptEl);
739
- });
740
- }
741
- }
742
- }
743
-
744
- function assignRemoteInfo(remoteInfo, remoteSnapshot) {
745
- const remoteEntryInfo = share.getRemoteEntryInfoFromSnapshot(remoteSnapshot);
746
- if (!remoteEntryInfo.url) {
747
- share.error(`The attribute remoteEntry of ${remoteInfo.name} must not be undefined.`);
748
- }
749
- let entryUrl = sdk.getResourceUrl(remoteSnapshot, remoteEntryInfo.url);
750
- if (!sdk.isBrowserEnv() && !entryUrl.startsWith('http')) {
751
- entryUrl = `https:${entryUrl}`;
752
- }
753
- remoteInfo.type = remoteEntryInfo.type;
754
- remoteInfo.entryGlobalName = remoteEntryInfo.globalName;
755
- remoteInfo.entry = entryUrl;
756
- remoteInfo.version = remoteSnapshot.version;
757
- remoteInfo.buildVersion = remoteSnapshot.buildVersion;
758
- }
759
- function snapshotPlugin() {
760
- return {
761
- name: 'snapshot-plugin',
762
- async afterResolve (args) {
763
- const { remote, pkgNameOrAlias, expose, origin, remoteInfo } = args;
764
- if (!share.isRemoteInfoWithEntry(remote) || !share.isPureRemoteEntry(remote)) {
765
- const { remoteSnapshot, globalSnapshot } = await origin.snapshotHandler.loadRemoteSnapshotInfo(remote);
766
- assignRemoteInfo(remoteInfo, remoteSnapshot);
767
- // preloading assets
768
- const preloadOptions = {
769
- remote,
770
- preloadConfig: {
771
- nameOrAlias: pkgNameOrAlias,
772
- exposes: [
773
- expose
774
- ],
775
- resourceCategory: 'sync',
776
- share: false,
777
- depsRemote: false
778
- }
779
- };
780
- const assets = await origin.remoteHandler.hooks.lifecycle.generatePreloadAssets.emit({
781
- origin,
782
- preloadOptions,
783
- remoteInfo,
784
- remote,
785
- remoteSnapshot,
786
- globalSnapshot
787
- });
788
- if (assets) {
789
- preloadAssets(remoteInfo, origin, assets, false);
790
- }
791
- return polyfills._extends({}, args, {
792
- remoteSnapshot
793
- });
794
- }
795
- return args;
796
- }
797
- };
798
- }
799
-
800
- // name
801
- // name:version
802
- function splitId(id) {
803
- const splitInfo = id.split(':');
804
- if (splitInfo.length === 1) {
805
- return {
806
- name: splitInfo[0],
807
- version: undefined
808
- };
809
- } else if (splitInfo.length === 2) {
810
- return {
811
- name: splitInfo[0],
812
- version: splitInfo[1]
813
- };
814
- } else {
815
- return {
816
- name: splitInfo[1],
817
- version: splitInfo[2]
818
- };
819
- }
820
- }
821
- // Traverse all nodes in moduleInfo and traverse the entire snapshot
822
- function traverseModuleInfo(globalSnapshot, remoteInfo, traverse, isRoot, memo = {}, remoteSnapshot) {
823
- const id = share.getFMId(remoteInfo);
824
- const { value: snapshotValue } = share.getInfoWithoutType(globalSnapshot, id);
825
- const effectiveRemoteSnapshot = remoteSnapshot || snapshotValue;
826
- if (effectiveRemoteSnapshot && !sdk.isManifestProvider(effectiveRemoteSnapshot)) {
827
- traverse(effectiveRemoteSnapshot, remoteInfo, isRoot);
828
- if (effectiveRemoteSnapshot.remotesInfo) {
829
- const remoteKeys = Object.keys(effectiveRemoteSnapshot.remotesInfo);
830
- for (const key of remoteKeys){
831
- if (memo[key]) {
832
- continue;
833
- }
834
- memo[key] = true;
835
- const subRemoteInfo = splitId(key);
836
- const remoteValue = effectiveRemoteSnapshot.remotesInfo[key];
837
- traverseModuleInfo(globalSnapshot, {
838
- name: subRemoteInfo.name,
839
- version: remoteValue.matchedVersion
840
- }, traverse, false, memo, undefined);
841
- }
842
- }
843
- }
844
- }
845
- // eslint-disable-next-line max-lines-per-function
846
- function generatePreloadAssets(origin, preloadOptions, remote, globalSnapshot, remoteSnapshot) {
847
- const cssAssets = [];
848
- const jsAssets = [];
849
- const entryAssets = [];
850
- const loadedSharedJsAssets = new Set();
851
- const loadedSharedCssAssets = new Set();
852
- const { options } = origin;
853
- const { preloadConfig: rootPreloadConfig } = preloadOptions;
854
- const { depsRemote } = rootPreloadConfig;
855
- const memo = {};
856
- traverseModuleInfo(globalSnapshot, remote, (moduleInfoSnapshot, remoteInfo, isRoot)=>{
857
- let preloadConfig;
858
- if (isRoot) {
859
- preloadConfig = rootPreloadConfig;
860
- } else {
861
- if (Array.isArray(depsRemote)) {
862
- // eslint-disable-next-line array-callback-return
863
- const findPreloadConfig = depsRemote.find((remoteConfig)=>{
864
- if (remoteConfig.nameOrAlias === remoteInfo.name || remoteConfig.nameOrAlias === remoteInfo.alias) {
865
- return true;
866
- }
867
- return false;
868
- });
869
- if (!findPreloadConfig) {
870
- return;
871
- }
872
- preloadConfig = defaultPreloadArgs(findPreloadConfig);
873
- } else if (depsRemote === true) {
874
- preloadConfig = rootPreloadConfig;
875
- } else {
876
- return;
877
- }
878
- }
879
- const remoteEntryUrl = sdk.getResourceUrl(moduleInfoSnapshot, share.getRemoteEntryInfoFromSnapshot(moduleInfoSnapshot).url);
880
- if (remoteEntryUrl) {
881
- entryAssets.push({
882
- name: remoteInfo.name,
883
- moduleInfo: {
884
- name: remoteInfo.name,
885
- entry: remoteEntryUrl,
886
- type: 'remoteEntryType' in moduleInfoSnapshot ? moduleInfoSnapshot.remoteEntryType : 'global',
887
- entryGlobalName: 'globalName' in moduleInfoSnapshot ? moduleInfoSnapshot.globalName : remoteInfo.name,
888
- shareScope: '',
889
- version: 'version' in moduleInfoSnapshot ? moduleInfoSnapshot.version : undefined
890
- },
891
- url: remoteEntryUrl
892
- });
893
- }
894
- let moduleAssetsInfo = 'modules' in moduleInfoSnapshot ? moduleInfoSnapshot.modules : [];
895
- const normalizedPreloadExposes = normalizePreloadExposes(preloadConfig.exposes);
896
- if (normalizedPreloadExposes.length && 'modules' in moduleInfoSnapshot) {
897
- var _moduleInfoSnapshot_modules;
898
- moduleAssetsInfo = moduleInfoSnapshot == null ? void 0 : (_moduleInfoSnapshot_modules = moduleInfoSnapshot.modules) == null ? void 0 : _moduleInfoSnapshot_modules.reduce((assets, moduleAssetInfo)=>{
899
- if ((normalizedPreloadExposes == null ? void 0 : normalizedPreloadExposes.indexOf(moduleAssetInfo.moduleName)) !== -1) {
900
- assets.push(moduleAssetInfo);
901
- }
902
- return assets;
903
- }, []);
904
- }
905
- function handleAssets(assets) {
906
- const assetsRes = assets.map((asset)=>sdk.getResourceUrl(moduleInfoSnapshot, asset));
907
- if (preloadConfig.filter) {
908
- return assetsRes.filter(preloadConfig.filter);
909
- }
910
- return assetsRes;
911
- }
912
- if (moduleAssetsInfo) {
913
- const assetsLength = moduleAssetsInfo.length;
914
- for(let index = 0; index < assetsLength; index++){
915
- const assetsInfo = moduleAssetsInfo[index];
916
- const exposeFullPath = `${remoteInfo.name}/${assetsInfo.moduleName}`;
917
- origin.remoteHandler.hooks.lifecycle.handlePreloadModule.emit({
918
- id: assetsInfo.moduleName === '.' ? remoteInfo.name : exposeFullPath,
919
- name: remoteInfo.name,
920
- remoteSnapshot: moduleInfoSnapshot,
921
- preloadConfig,
922
- remote: remoteInfo,
923
- origin
924
- });
925
- const preloaded = share.getPreloaded(exposeFullPath);
926
- if (preloaded) {
927
- continue;
928
- }
929
- if (preloadConfig.resourceCategory === 'all') {
930
- cssAssets.push(...handleAssets(assetsInfo.assets.css.async));
931
- cssAssets.push(...handleAssets(assetsInfo.assets.css.sync));
932
- jsAssets.push(...handleAssets(assetsInfo.assets.js.async));
933
- jsAssets.push(...handleAssets(assetsInfo.assets.js.sync));
934
- // eslint-disable-next-line no-constant-condition
935
- } else if (preloadConfig.resourceCategory = 'sync') {
936
- cssAssets.push(...handleAssets(assetsInfo.assets.css.sync));
937
- jsAssets.push(...handleAssets(assetsInfo.assets.js.sync));
938
- }
939
- share.setPreloaded(exposeFullPath);
940
- }
941
- }
942
- }, true, memo, remoteSnapshot);
943
- if (remoteSnapshot.shared) {
944
- const collectSharedAssets = (shareInfo, snapshotShared)=>{
945
- const registeredShared = share.getRegisteredShare(origin.shareScopeMap, snapshotShared.sharedName, shareInfo, origin.sharedHandler.hooks.lifecycle.resolveShare);
946
- // If the global share does not exist, or the lib function does not exist, it means that the shared has not been loaded yet and can be preloaded.
947
- if (registeredShared && typeof registeredShared.lib === 'function') {
948
- snapshotShared.assets.js.sync.forEach((asset)=>{
949
- loadedSharedJsAssets.add(asset);
950
- });
951
- snapshotShared.assets.css.sync.forEach((asset)=>{
952
- loadedSharedCssAssets.add(asset);
953
- });
954
- }
955
- };
956
- remoteSnapshot.shared.forEach((shared)=>{
957
- var _options_shared;
958
- const shareInfos = (_options_shared = options.shared) == null ? void 0 : _options_shared[shared.sharedName];
959
- if (!shareInfos) {
960
- return;
961
- }
962
- // if no version, preload all shared
963
- const sharedOptions = shared.version ? shareInfos.find((s)=>s.version === shared.version) : shareInfos;
964
- if (!sharedOptions) {
965
- return;
966
- }
967
- const arrayShareInfo = share.arrayOptions(sharedOptions);
968
- arrayShareInfo.forEach((s)=>{
969
- collectSharedAssets(s, shared);
970
- });
971
- });
972
- }
973
- const needPreloadJsAssets = jsAssets.filter((asset)=>!loadedSharedJsAssets.has(asset));
974
- const needPreloadCssAssets = cssAssets.filter((asset)=>!loadedSharedCssAssets.has(asset));
975
- return {
976
- cssAssets: needPreloadCssAssets,
977
- jsAssetsWithoutEntry: needPreloadJsAssets,
978
- entryAssets
979
- };
980
- }
981
- const generatePreloadAssetsPlugin = function() {
982
- return {
983
- name: 'generate-preload-assets-plugin',
984
- async generatePreloadAssets (args) {
985
- const { origin, preloadOptions, remoteInfo, remote, globalSnapshot, remoteSnapshot } = args;
986
- if (share.isRemoteInfoWithEntry(remote) && share.isPureRemoteEntry(remote)) {
987
- return {
988
- cssAssets: [],
989
- jsAssetsWithoutEntry: [],
990
- entryAssets: [
991
- {
992
- name: remote.name,
993
- url: remote.entry,
994
- moduleInfo: {
995
- name: remoteInfo.name,
996
- entry: remote.entry,
997
- type: remoteInfo.type || 'global',
998
- entryGlobalName: '',
999
- shareScope: ''
1000
- }
1001
- }
1002
- ]
1003
- };
1004
- }
1005
- assignRemoteInfo(remoteInfo, remoteSnapshot);
1006
- const assets = generatePreloadAssets(origin, preloadOptions, remoteInfo, globalSnapshot, remoteSnapshot);
1007
- return assets;
1008
- }
1009
- };
1010
- };
1011
-
1012
- function getGlobalRemoteInfo(moduleInfo, origin) {
1013
- const hostGlobalSnapshot = share.getGlobalSnapshotInfoByModuleInfo({
1014
- name: origin.options.name,
1015
- version: origin.options.version
1016
- });
1017
- // get remote detail info from global
1018
- const globalRemoteInfo = hostGlobalSnapshot && 'remotesInfo' in hostGlobalSnapshot && hostGlobalSnapshot.remotesInfo && share.getInfoWithoutType(hostGlobalSnapshot.remotesInfo, moduleInfo.name).value;
1019
- if (globalRemoteInfo && globalRemoteInfo.matchedVersion) {
1020
- return {
1021
- hostGlobalSnapshot,
1022
- globalSnapshot: share.getGlobalSnapshot(),
1023
- remoteSnapshot: share.getGlobalSnapshotInfoByModuleInfo({
1024
- name: moduleInfo.name,
1025
- version: globalRemoteInfo.matchedVersion
1026
- })
1027
- };
1028
- }
1029
- return {
1030
- hostGlobalSnapshot: undefined,
1031
- globalSnapshot: share.getGlobalSnapshot(),
1032
- remoteSnapshot: share.getGlobalSnapshotInfoByModuleInfo({
1033
- name: moduleInfo.name,
1034
- version: 'version' in moduleInfo ? moduleInfo.version : undefined
1035
- })
1036
- };
1037
- }
1038
- class SnapshotHandler {
1039
- async loadSnapshot(moduleInfo) {
1040
- const { options } = this.HostInstance;
1041
- const { hostGlobalSnapshot, remoteSnapshot, globalSnapshot } = this.getGlobalRemoteInfo(moduleInfo);
1042
- const { remoteSnapshot: globalRemoteSnapshot, globalSnapshot: globalSnapshotRes } = await this.hooks.lifecycle.loadSnapshot.emit({
1043
- options,
1044
- moduleInfo,
1045
- hostGlobalSnapshot,
1046
- remoteSnapshot,
1047
- globalSnapshot
1048
- });
1049
- return {
1050
- remoteSnapshot: globalRemoteSnapshot,
1051
- globalSnapshot: globalSnapshotRes
1052
- };
1053
- }
1054
- // eslint-disable-next-line max-lines-per-function
1055
- async loadRemoteSnapshotInfo(moduleInfo) {
1056
- const { options } = this.HostInstance;
1057
- await this.hooks.lifecycle.beforeLoadRemoteSnapshot.emit({
1058
- options,
1059
- moduleInfo
1060
- });
1061
- let hostSnapshot = share.getGlobalSnapshotInfoByModuleInfo({
1062
- name: this.HostInstance.options.name,
1063
- version: this.HostInstance.options.version
1064
- });
1065
- if (!hostSnapshot) {
1066
- hostSnapshot = {
1067
- version: this.HostInstance.options.version || '',
1068
- remoteEntry: '',
1069
- remotesInfo: {}
1070
- };
1071
- share.addGlobalSnapshot({
1072
- [this.HostInstance.options.name]: hostSnapshot
1073
- });
1074
- }
1075
- // In dynamic loadRemote scenarios, incomplete remotesInfo delivery may occur. In such cases, the remotesInfo in the host needs to be completed in the snapshot at runtime.
1076
- // This ensures the snapshot's integrity and helps the chrome plugin correctly identify all producer modules, ensuring that proxyable producer modules will not be missing.
1077
- if (hostSnapshot && 'remotesInfo' in hostSnapshot && !share.getInfoWithoutType(hostSnapshot.remotesInfo, moduleInfo.name).value) {
1078
- if ('version' in moduleInfo || 'entry' in moduleInfo) {
1079
- hostSnapshot.remotesInfo = polyfills._extends({}, hostSnapshot == null ? void 0 : hostSnapshot.remotesInfo, {
1080
- [moduleInfo.name]: {
1081
- matchedVersion: 'version' in moduleInfo ? moduleInfo.version : moduleInfo.entry
1082
- }
1083
- });
1084
- }
1085
- }
1086
- const { hostGlobalSnapshot, remoteSnapshot, globalSnapshot } = this.getGlobalRemoteInfo(moduleInfo);
1087
- const { remoteSnapshot: globalRemoteSnapshot, globalSnapshot: globalSnapshotRes } = await this.hooks.lifecycle.loadSnapshot.emit({
1088
- options,
1089
- moduleInfo,
1090
- hostGlobalSnapshot,
1091
- remoteSnapshot,
1092
- globalSnapshot
1093
- });
1094
- let mSnapshot;
1095
- let gSnapshot;
1096
- // global snapshot includes manifest or module info includes manifest
1097
- if (globalRemoteSnapshot) {
1098
- if (sdk.isManifestProvider(globalRemoteSnapshot)) {
1099
- const remoteEntry = sdk.isBrowserEnv() ? globalRemoteSnapshot.remoteEntry : globalRemoteSnapshot.ssrRemoteEntry || globalRemoteSnapshot.remoteEntry || '';
1100
- const moduleSnapshot = await this.getManifestJson(remoteEntry, moduleInfo, {});
1101
- // eslint-disable-next-line @typescript-eslint/no-shadow
1102
- const globalSnapshotRes = share.setGlobalSnapshotInfoByModuleInfo(polyfills._extends({}, moduleInfo, {
1103
- // The global remote may be overridden
1104
- // Therefore, set the snapshot key to the global address of the actual request
1105
- entry: remoteEntry
1106
- }), moduleSnapshot);
1107
- mSnapshot = moduleSnapshot;
1108
- gSnapshot = globalSnapshotRes;
1109
- } else {
1110
- const { remoteSnapshot: remoteSnapshotRes } = await this.hooks.lifecycle.loadRemoteSnapshot.emit({
1111
- options: this.HostInstance.options,
1112
- moduleInfo,
1113
- remoteSnapshot: globalRemoteSnapshot,
1114
- from: 'global'
1115
- });
1116
- mSnapshot = remoteSnapshotRes;
1117
- gSnapshot = globalSnapshotRes;
1118
- }
1119
- } else {
1120
- if (share.isRemoteInfoWithEntry(moduleInfo)) {
1121
- // get from manifest.json and merge remote info from remote server
1122
- const moduleSnapshot = await this.getManifestJson(moduleInfo.entry, moduleInfo, {});
1123
- // eslint-disable-next-line @typescript-eslint/no-shadow
1124
- const globalSnapshotRes = share.setGlobalSnapshotInfoByModuleInfo(moduleInfo, moduleSnapshot);
1125
- const { remoteSnapshot: remoteSnapshotRes } = await this.hooks.lifecycle.loadRemoteSnapshot.emit({
1126
- options: this.HostInstance.options,
1127
- moduleInfo,
1128
- remoteSnapshot: moduleSnapshot,
1129
- from: 'global'
1130
- });
1131
- mSnapshot = remoteSnapshotRes;
1132
- gSnapshot = globalSnapshotRes;
1133
- } else {
1134
- share.error(errorCodes.getShortErrorMsg(errorCodes.RUNTIME_007, errorCodes.runtimeDescMap, {
1135
- hostName: moduleInfo.name,
1136
- hostVersion: moduleInfo.version,
1137
- globalSnapshot: JSON.stringify(globalSnapshotRes)
1138
- }));
1139
- }
1140
- }
1141
- await this.hooks.lifecycle.afterLoadSnapshot.emit({
1142
- options,
1143
- moduleInfo,
1144
- remoteSnapshot: mSnapshot
1145
- });
1146
- return {
1147
- remoteSnapshot: mSnapshot,
1148
- globalSnapshot: gSnapshot
1149
- };
1150
- }
1151
- getGlobalRemoteInfo(moduleInfo) {
1152
- return getGlobalRemoteInfo(moduleInfo, this.HostInstance);
1153
- }
1154
- async getManifestJson(manifestUrl, moduleInfo, extraOptions) {
1155
- const getManifest = async ()=>{
1156
- let manifestJson = this.manifestCache.get(manifestUrl);
1157
- if (manifestJson) {
1158
- return manifestJson;
1159
- }
1160
- try {
1161
- let res = await this.loaderHook.lifecycle.fetch.emit(manifestUrl, {});
1162
- if (!res || !(res instanceof Response)) {
1163
- res = await fetch(manifestUrl, {});
1164
- }
1165
- manifestJson = await res.json();
1166
- share.assert(manifestJson.metaData && manifestJson.exposes && manifestJson.shared, `${manifestUrl} is not a federation manifest`);
1167
- this.manifestCache.set(manifestUrl, manifestJson);
1168
- return manifestJson;
1169
- } catch (err) {
1170
- delete this.manifestLoading[manifestUrl];
1171
- share.error(errorCodes.getShortErrorMsg(errorCodes.RUNTIME_003, errorCodes.runtimeDescMap, {
1172
- manifestUrl,
1173
- moduleName: moduleInfo.name
1174
- }, `${err}`));
1175
- }
1176
- };
1177
- const asyncLoadProcess = async ()=>{
1178
- const manifestJson = await getManifest();
1179
- const remoteSnapshot = sdk.generateSnapshotFromManifest(manifestJson, {
1180
- version: manifestUrl
1181
- });
1182
- const { remoteSnapshot: remoteSnapshotRes } = await this.hooks.lifecycle.loadRemoteSnapshot.emit({
1183
- options: this.HostInstance.options,
1184
- moduleInfo,
1185
- manifestJson,
1186
- remoteSnapshot,
1187
- manifestUrl,
1188
- from: 'manifest'
1189
- });
1190
- return remoteSnapshotRes;
1191
- };
1192
- if (!this.manifestLoading[manifestUrl]) {
1193
- this.manifestLoading[manifestUrl] = asyncLoadProcess().then((res)=>res);
1194
- }
1195
- return this.manifestLoading[manifestUrl];
1196
- }
1197
- constructor(HostInstance){
1198
- this.loadingHostSnapshot = null;
1199
- this.manifestCache = new Map();
1200
- this.hooks = new PluginSystem({
1201
- beforeLoadRemoteSnapshot: new AsyncHook('beforeLoadRemoteSnapshot'),
1202
- loadSnapshot: new AsyncWaterfallHook('loadGlobalSnapshot'),
1203
- loadRemoteSnapshot: new AsyncWaterfallHook('loadRemoteSnapshot'),
1204
- afterLoadSnapshot: new AsyncWaterfallHook('afterLoadSnapshot')
1205
- });
1206
- this.manifestLoading = share.Global.__FEDERATION__.__MANIFEST_LOADING__;
1207
- this.HostInstance = HostInstance;
1208
- this.loaderHook = HostInstance.loaderHook;
1209
- }
1210
- }
1211
-
1212
- class SharedHandler {
1213
- // register shared in shareScopeMap
1214
- registerShared(globalOptions, userOptions) {
1215
- const { shareInfos, shared } = share.formatShareConfigs(globalOptions, userOptions);
1216
- const sharedKeys = Object.keys(shareInfos);
1217
- sharedKeys.forEach((sharedKey)=>{
1218
- const sharedVals = shareInfos[sharedKey];
1219
- sharedVals.forEach((sharedVal)=>{
1220
- const registeredShared = share.getRegisteredShare(this.shareScopeMap, sharedKey, sharedVal, this.hooks.lifecycle.resolveShare);
1221
- if (!registeredShared && sharedVal && sharedVal.lib) {
1222
- this.setShared({
1223
- pkgName: sharedKey,
1224
- lib: sharedVal.lib,
1225
- get: sharedVal.get,
1226
- loaded: true,
1227
- shared: sharedVal,
1228
- from: userOptions.name
1229
- });
1230
- }
1231
- });
1232
- });
1233
- return {
1234
- shareInfos,
1235
- shared
1236
- };
1237
- }
1238
- async loadShare(pkgName, extraOptions) {
1239
- const { host } = this;
1240
- // This function performs the following steps:
1241
- // 1. Checks if the currently loaded share already exists, if not, it throws an error
1242
- // 2. Searches globally for a matching share, if found, it uses it directly
1243
- // 3. If not found, it retrieves it from the current share and stores the obtained share globally.
1244
- const shareInfo = share.getTargetSharedOptions({
1245
- pkgName,
1246
- extraOptions,
1247
- shareInfos: host.options.shared
1248
- });
1249
- if (shareInfo == null ? void 0 : shareInfo.scope) {
1250
- await Promise.all(shareInfo.scope.map(async (shareScope)=>{
1251
- await Promise.all(this.initializeSharing(shareScope, {
1252
- strategy: shareInfo.strategy
1253
- }));
1254
- return;
1255
- }));
1256
- }
1257
- const loadShareRes = await this.hooks.lifecycle.beforeLoadShare.emit({
1258
- pkgName,
1259
- shareInfo,
1260
- shared: host.options.shared,
1261
- origin: host
1262
- });
1263
- const { shareInfo: shareInfoRes } = loadShareRes;
1264
- // Assert that shareInfoRes exists, if not, throw an error
1265
- share.assert(shareInfoRes, `Cannot find ${pkgName} Share in the ${host.options.name}. Please ensure that the ${pkgName} Share parameters have been injected`);
1266
- // Retrieve from cache
1267
- const registeredShared = share.getRegisteredShare(this.shareScopeMap, pkgName, shareInfoRes, this.hooks.lifecycle.resolveShare);
1268
- const addUseIn = (shared)=>{
1269
- if (!shared.useIn) {
1270
- shared.useIn = [];
1271
- }
1272
- share.addUniqueItem(shared.useIn, host.options.name);
1273
- };
1274
- if (registeredShared && registeredShared.lib) {
1275
- addUseIn(registeredShared);
1276
- return registeredShared.lib;
1277
- } else if (registeredShared && registeredShared.loading && !registeredShared.loaded) {
1278
- const factory = await registeredShared.loading;
1279
- registeredShared.loaded = true;
1280
- if (!registeredShared.lib) {
1281
- registeredShared.lib = factory;
1282
- }
1283
- addUseIn(registeredShared);
1284
- return factory;
1285
- } else if (registeredShared) {
1286
- const asyncLoadProcess = async ()=>{
1287
- const factory = await registeredShared.get();
1288
- shareInfoRes.lib = factory;
1289
- shareInfoRes.loaded = true;
1290
- addUseIn(shareInfoRes);
1291
- const gShared = share.getRegisteredShare(this.shareScopeMap, pkgName, shareInfoRes, this.hooks.lifecycle.resolveShare);
1292
- if (gShared) {
1293
- gShared.lib = factory;
1294
- gShared.loaded = true;
1295
- }
1296
- return factory;
1297
- };
1298
- const loading = asyncLoadProcess();
1299
- this.setShared({
1300
- pkgName,
1301
- loaded: false,
1302
- shared: registeredShared,
1303
- from: host.options.name,
1304
- lib: null,
1305
- loading
1306
- });
1307
- return loading;
1308
- } else {
1309
- if (extraOptions == null ? void 0 : extraOptions.customShareInfo) {
1310
- return false;
1311
- }
1312
- const asyncLoadProcess = async ()=>{
1313
- const factory = await shareInfoRes.get();
1314
- shareInfoRes.lib = factory;
1315
- shareInfoRes.loaded = true;
1316
- addUseIn(shareInfoRes);
1317
- const gShared = share.getRegisteredShare(this.shareScopeMap, pkgName, shareInfoRes, this.hooks.lifecycle.resolveShare);
1318
- if (gShared) {
1319
- gShared.lib = factory;
1320
- gShared.loaded = true;
1321
- }
1322
- return factory;
1323
- };
1324
- const loading = asyncLoadProcess();
1325
- this.setShared({
1326
- pkgName,
1327
- loaded: false,
1328
- shared: shareInfoRes,
1329
- from: host.options.name,
1330
- lib: null,
1331
- loading
1332
- });
1333
- return loading;
1334
- }
1335
- }
1336
- /**
1337
- * This function initializes the sharing sequence (executed only once per share scope).
1338
- * It accepts one argument, the name of the share scope.
1339
- * If the share scope does not exist, it creates one.
1340
- */ // eslint-disable-next-line @typescript-eslint/member-ordering
1341
- initializeSharing(shareScopeName = share.DEFAULT_SCOPE, extraOptions) {
1342
- const { host } = this;
1343
- const from = extraOptions == null ? void 0 : extraOptions.from;
1344
- const strategy = extraOptions == null ? void 0 : extraOptions.strategy;
1345
- let initScope = extraOptions == null ? void 0 : extraOptions.initScope;
1346
- const promises = [];
1347
- if (from !== 'build') {
1348
- const { initTokens } = this;
1349
- if (!initScope) initScope = [];
1350
- let initToken = initTokens[shareScopeName];
1351
- if (!initToken) initToken = initTokens[shareScopeName] = {
1352
- from: this.host.name
1353
- };
1354
- if (initScope.indexOf(initToken) >= 0) return promises;
1355
- initScope.push(initToken);
1356
- }
1357
- const shareScope = this.shareScopeMap;
1358
- const hostName = host.options.name;
1359
- // Creates a new share scope if necessary
1360
- if (!shareScope[shareScopeName]) {
1361
- shareScope[shareScopeName] = {};
1362
- }
1363
- // Executes all initialization snippets from all accessible modules
1364
- const scope = shareScope[shareScopeName];
1365
- const register = (name, shared)=>{
1366
- var _activeVersion_shareConfig;
1367
- const { version, eager } = shared;
1368
- scope[name] = scope[name] || {};
1369
- const versions = scope[name];
1370
- const activeVersion = versions[version];
1371
- const activeVersionEager = Boolean(activeVersion && (activeVersion.eager || ((_activeVersion_shareConfig = activeVersion.shareConfig) == null ? void 0 : _activeVersion_shareConfig.eager)));
1372
- if (!activeVersion || activeVersion.strategy !== 'loaded-first' && !activeVersion.loaded && (Boolean(!eager) !== !activeVersionEager ? eager : hostName > activeVersion.from)) {
1373
- versions[version] = shared;
1374
- }
1375
- };
1376
- const initFn = (mod)=>mod && mod.init && mod.init(shareScope[shareScopeName], initScope);
1377
- const initRemoteModule = async (key)=>{
1378
- const { module } = await host.remoteHandler.getRemoteModuleAndOptions({
1379
- id: key
1380
- });
1381
- if (module.getEntry) {
1382
- let remoteEntryExports;
1383
- try {
1384
- remoteEntryExports = await module.getEntry();
1385
- } catch (error) {
1386
- remoteEntryExports = await host.remoteHandler.hooks.lifecycle.errorLoadRemote.emit({
1387
- id: key,
1388
- error,
1389
- from: 'runtime',
1390
- lifecycle: 'beforeLoadShare',
1391
- origin: host
1392
- });
1393
- }
1394
- if (!module.inited) {
1395
- await initFn(remoteEntryExports);
1396
- module.inited = true;
1397
- }
1398
- }
1399
- };
1400
- Object.keys(host.options.shared).forEach((shareName)=>{
1401
- const sharedArr = host.options.shared[shareName];
1402
- sharedArr.forEach((shared)=>{
1403
- if (shared.scope.includes(shareScopeName)) {
1404
- register(shareName, shared);
1405
- }
1406
- });
1407
- });
1408
- // TODO: strategy==='version-first' need to be removed in the future
1409
- if (host.options.shareStrategy === 'version-first' || strategy === 'version-first') {
1410
- host.options.remotes.forEach((remote)=>{
1411
- if (remote.shareScope === shareScopeName) {
1412
- promises.push(initRemoteModule(remote.name));
1413
- }
1414
- });
1415
- }
1416
- return promises;
1417
- }
1418
- // The lib function will only be available if the shared set by eager or runtime init is set or the shared is successfully loaded.
1419
- // 1. If the loaded shared already exists globally, then it will be reused
1420
- // 2. If lib exists in local shared, it will be used directly
1421
- // 3. If the local get returns something other than Promise, then it will be used directly
1422
- loadShareSync(pkgName, extraOptions) {
1423
- const { host } = this;
1424
- const shareInfo = share.getTargetSharedOptions({
1425
- pkgName,
1426
- extraOptions,
1427
- shareInfos: host.options.shared
1428
- });
1429
- if (shareInfo == null ? void 0 : shareInfo.scope) {
1430
- shareInfo.scope.forEach((shareScope)=>{
1431
- this.initializeSharing(shareScope, {
1432
- strategy: shareInfo.strategy
1433
- });
1434
- });
1435
- }
1436
- const registeredShared = share.getRegisteredShare(this.shareScopeMap, pkgName, shareInfo, this.hooks.lifecycle.resolveShare);
1437
- const addUseIn = (shared)=>{
1438
- if (!shared.useIn) {
1439
- shared.useIn = [];
1440
- }
1441
- share.addUniqueItem(shared.useIn, host.options.name);
1442
- };
1443
- if (registeredShared) {
1444
- if (typeof registeredShared.lib === 'function') {
1445
- addUseIn(registeredShared);
1446
- if (!registeredShared.loaded) {
1447
- registeredShared.loaded = true;
1448
- if (registeredShared.from === host.options.name) {
1449
- shareInfo.loaded = true;
1450
- }
1451
- }
1452
- return registeredShared.lib;
1453
- }
1454
- if (typeof registeredShared.get === 'function') {
1455
- const module = registeredShared.get();
1456
- if (!(module instanceof Promise)) {
1457
- addUseIn(registeredShared);
1458
- this.setShared({
1459
- pkgName,
1460
- loaded: true,
1461
- from: host.options.name,
1462
- lib: module,
1463
- shared: registeredShared
1464
- });
1465
- return module;
1466
- }
1467
- }
1468
- }
1469
- if (shareInfo.lib) {
1470
- if (!shareInfo.loaded) {
1471
- shareInfo.loaded = true;
1472
- }
1473
- return shareInfo.lib;
1474
- }
1475
- if (shareInfo.get) {
1476
- const module = shareInfo.get();
1477
- if (module instanceof Promise) {
1478
- const errorCode = (extraOptions == null ? void 0 : extraOptions.from) === 'build' ? errorCodes.RUNTIME_005 : errorCodes.RUNTIME_006;
1479
- throw new Error(errorCodes.getShortErrorMsg(errorCode, errorCodes.runtimeDescMap, {
1480
- hostName: host.options.name,
1481
- sharedPkgName: pkgName
1482
- }));
1483
- }
1484
- shareInfo.lib = module;
1485
- this.setShared({
1486
- pkgName,
1487
- loaded: true,
1488
- from: host.options.name,
1489
- lib: shareInfo.lib,
1490
- shared: shareInfo
1491
- });
1492
- return shareInfo.lib;
1493
- }
1494
- throw new Error(errorCodes.getShortErrorMsg(errorCodes.RUNTIME_006, errorCodes.runtimeDescMap, {
1495
- hostName: host.options.name,
1496
- sharedPkgName: pkgName
1497
- }));
1498
- }
1499
- initShareScopeMap(scopeName, shareScope, extraOptions = {}) {
1500
- const { host } = this;
1501
- this.shareScopeMap[scopeName] = shareScope;
1502
- this.hooks.lifecycle.initContainerShareScopeMap.emit({
1503
- shareScope,
1504
- options: host.options,
1505
- origin: host,
1506
- scopeName,
1507
- hostShareScopeMap: extraOptions.hostShareScopeMap
1508
- });
1509
- }
1510
- setShared({ pkgName, shared, from, lib, loading, loaded, get }) {
1511
- const { version, scope = 'default' } = shared, shareInfo = polyfills._object_without_properties_loose(shared, [
1512
- "version",
1513
- "scope"
1514
- ]);
1515
- const scopes = Array.isArray(scope) ? scope : [
1516
- scope
1517
- ];
1518
- scopes.forEach((sc)=>{
1519
- if (!this.shareScopeMap[sc]) {
1520
- this.shareScopeMap[sc] = {};
1521
- }
1522
- if (!this.shareScopeMap[sc][pkgName]) {
1523
- this.shareScopeMap[sc][pkgName] = {};
1524
- }
1525
- if (!this.shareScopeMap[sc][pkgName][version]) {
1526
- this.shareScopeMap[sc][pkgName][version] = polyfills._extends({
1527
- version,
1528
- scope: [
1529
- 'default'
1530
- ]
1531
- }, shareInfo, {
1532
- lib,
1533
- loaded,
1534
- loading
1535
- });
1536
- if (get) {
1537
- this.shareScopeMap[sc][pkgName][version].get = get;
1538
- }
1539
- return;
1540
- }
1541
- const registeredShared = this.shareScopeMap[sc][pkgName][version];
1542
- if (loading && !registeredShared.loading) {
1543
- registeredShared.loading = loading;
1544
- }
1545
- });
1546
- }
1547
- _setGlobalShareScopeMap(hostOptions) {
1548
- const globalShareScopeMap = share.getGlobalShareScope();
1549
- const identifier = hostOptions.id || hostOptions.name;
1550
- if (identifier && !globalShareScopeMap[identifier]) {
1551
- globalShareScopeMap[identifier] = this.shareScopeMap;
1552
- }
1553
- }
1554
- constructor(host){
1555
- this.hooks = new PluginSystem({
1556
- afterResolve: new AsyncWaterfallHook('afterResolve'),
1557
- beforeLoadShare: new AsyncWaterfallHook('beforeLoadShare'),
1558
- // not used yet
1559
- loadShare: new AsyncHook(),
1560
- resolveShare: new SyncWaterfallHook('resolveShare'),
1561
- // maybe will change, temporarily for internal use only
1562
- initContainerShareScopeMap: new SyncWaterfallHook('initContainerShareScopeMap')
1563
- });
1564
- this.host = host;
1565
- this.shareScopeMap = {};
1566
- this.initTokens = {};
1567
- this._setGlobalShareScopeMap(host.options);
1568
- }
1569
- }
1570
-
1571
- class RemoteHandler {
1572
- formatAndRegisterRemote(globalOptions, userOptions) {
1573
- const userRemotes = userOptions.remotes || [];
1574
- return userRemotes.reduce((res, remote)=>{
1575
- this.registerRemote(remote, res, {
1576
- force: false
1577
- });
1578
- return res;
1579
- }, globalOptions.remotes);
1580
- }
1581
- setIdToRemoteMap(id, remoteMatchInfo) {
1582
- const { remote, expose } = remoteMatchInfo;
1583
- const { name, alias } = remote;
1584
- this.idToRemoteMap[id] = {
1585
- name: remote.name,
1586
- expose
1587
- };
1588
- if (alias && id.startsWith(name)) {
1589
- const idWithAlias = id.replace(name, alias);
1590
- this.idToRemoteMap[idWithAlias] = {
1591
- name: remote.name,
1592
- expose
1593
- };
1594
- return;
1595
- }
1596
- if (alias && id.startsWith(alias)) {
1597
- const idWithName = id.replace(alias, name);
1598
- this.idToRemoteMap[idWithName] = {
1599
- name: remote.name,
1600
- expose
1601
- };
1602
- }
1603
- }
1604
- // eslint-disable-next-line max-lines-per-function
1605
- // eslint-disable-next-line @typescript-eslint/member-ordering
1606
- async loadRemote(id, options) {
1607
- const { host } = this;
1608
- try {
1609
- const { loadFactory = true } = options || {
1610
- loadFactory: true
1611
- };
1612
- // 1. Validate the parameters of the retrieved module. There are two module request methods: pkgName + expose and alias + expose.
1613
- // 2. Request the snapshot information of the current host and globally store the obtained snapshot information. The retrieved module information is partially offline and partially online. The online module information will retrieve the modules used online.
1614
- // 3. Retrieve the detailed information of the current module from global (remoteEntry address, expose resource address)
1615
- // 4. After retrieving remoteEntry, call the init of the module, and then retrieve the exported content of the module through get
1616
- // id: pkgName(@federation/app1) + expose(button) = @federation/app1/button
1617
- // id: alias(app1) + expose(button) = app1/button
1618
- // id: alias(app1/utils) + expose(loadash/sort) = app1/utils/loadash/sort
1619
- const { module, moduleOptions, remoteMatchInfo } = await this.getRemoteModuleAndOptions({
1620
- id
1621
- });
1622
- const { pkgNameOrAlias, remote, expose, id: idRes, remoteSnapshot } = remoteMatchInfo;
1623
- const moduleOrFactory = await module.get(idRes, expose, options, remoteSnapshot);
1624
- const moduleWrapper = await this.hooks.lifecycle.onLoad.emit({
1625
- id: idRes,
1626
- pkgNameOrAlias,
1627
- expose,
1628
- exposeModule: loadFactory ? moduleOrFactory : undefined,
1629
- exposeModuleFactory: loadFactory ? undefined : moduleOrFactory,
1630
- remote,
1631
- options: moduleOptions,
1632
- moduleInstance: module,
1633
- origin: host
1634
- });
1635
- this.setIdToRemoteMap(id, remoteMatchInfo);
1636
- if (typeof moduleWrapper === 'function') {
1637
- return moduleWrapper;
1638
- }
1639
- return moduleOrFactory;
1640
- } catch (error) {
1641
- const { from = 'runtime' } = options || {
1642
- from: 'runtime'
1643
- };
1644
- const failOver = await this.hooks.lifecycle.errorLoadRemote.emit({
1645
- id,
1646
- error,
1647
- from,
1648
- lifecycle: 'onLoad',
1649
- origin: host
1650
- });
1651
- if (!failOver) {
1652
- throw error;
1653
- }
1654
- return failOver;
1655
- }
1656
- }
1657
- // eslint-disable-next-line @typescript-eslint/member-ordering
1658
- async preloadRemote(preloadOptions) {
1659
- const { host } = this;
1660
- await this.hooks.lifecycle.beforePreloadRemote.emit({
1661
- preloadOps: preloadOptions,
1662
- options: host.options,
1663
- origin: host
1664
- });
1665
- const preloadOps = formatPreloadArgs(host.options.remotes, preloadOptions);
1666
- await Promise.all(preloadOps.map(async (ops)=>{
1667
- const { remote } = ops;
1668
- const remoteInfo = getRemoteInfo(remote);
1669
- const { globalSnapshot, remoteSnapshot } = await host.snapshotHandler.loadRemoteSnapshotInfo(remote);
1670
- const assets = await this.hooks.lifecycle.generatePreloadAssets.emit({
1671
- origin: host,
1672
- preloadOptions: ops,
1673
- remote,
1674
- remoteInfo,
1675
- globalSnapshot,
1676
- remoteSnapshot
1677
- });
1678
- if (!assets) {
1679
- return;
1680
- }
1681
- preloadAssets(remoteInfo, host, assets);
1682
- }));
1683
- }
1684
- registerRemotes(remotes, options) {
1685
- const { host } = this;
1686
- remotes.forEach((remote)=>{
1687
- this.registerRemote(remote, host.options.remotes, {
1688
- force: options == null ? void 0 : options.force
1689
- });
1690
- });
1691
- }
1692
- async getRemoteModuleAndOptions(options) {
1693
- const { host } = this;
1694
- const { id } = options;
1695
- let loadRemoteArgs;
1696
- try {
1697
- loadRemoteArgs = await this.hooks.lifecycle.beforeRequest.emit({
1698
- id,
1699
- options: host.options,
1700
- origin: host
1701
- });
1702
- } catch (error) {
1703
- loadRemoteArgs = await this.hooks.lifecycle.errorLoadRemote.emit({
1704
- id,
1705
- options: host.options,
1706
- origin: host,
1707
- from: 'runtime',
1708
- error,
1709
- lifecycle: 'beforeRequest'
1710
- });
1711
- if (!loadRemoteArgs) {
1712
- throw error;
1713
- }
1714
- }
1715
- const { id: idRes } = loadRemoteArgs;
1716
- const remoteSplitInfo = matchRemoteWithNameAndExpose(host.options.remotes, idRes);
1717
- share.assert(remoteSplitInfo, errorCodes.getShortErrorMsg(errorCodes.RUNTIME_004, errorCodes.runtimeDescMap, {
1718
- hostName: host.options.name,
1719
- requestId: idRes
1720
- }));
1721
- const { remote: rawRemote } = remoteSplitInfo;
1722
- const remoteInfo = getRemoteInfo(rawRemote);
1723
- const matchInfo = await host.sharedHandler.hooks.lifecycle.afterResolve.emit(polyfills._extends({
1724
- id: idRes
1725
- }, remoteSplitInfo, {
1726
- options: host.options,
1727
- origin: host,
1728
- remoteInfo
1729
- }));
1730
- const { remote, expose } = matchInfo;
1731
- share.assert(remote && expose, `The 'beforeRequest' hook was executed, but it failed to return the correct 'remote' and 'expose' values while loading ${idRes}.`);
1732
- let module = host.moduleCache.get(remote.name);
1733
- const moduleOptions = {
1734
- host: host,
1735
- remoteInfo
1736
- };
1737
- if (!module) {
1738
- module = new Module(moduleOptions);
1739
- host.moduleCache.set(remote.name, module);
1740
- }
1741
- return {
1742
- module,
1743
- moduleOptions,
1744
- remoteMatchInfo: matchInfo
1745
- };
1746
- }
1747
- registerRemote(remote, targetRemotes, options) {
1748
- const { host } = this;
1749
- const normalizeRemote = ()=>{
1750
- if (remote.alias) {
1751
- // Validate if alias equals the prefix of remote.name and remote.alias, if so, throw an error
1752
- // As multi-level path references cannot guarantee unique names, alias being a prefix of remote.name is not supported
1753
- const findEqual = targetRemotes.find((item)=>{
1754
- var _item_alias;
1755
- return remote.alias && (item.name.startsWith(remote.alias) || ((_item_alias = item.alias) == null ? void 0 : _item_alias.startsWith(remote.alias)));
1756
- });
1757
- share.assert(!findEqual, `The alias ${remote.alias} of remote ${remote.name} is not allowed to be the prefix of ${findEqual && findEqual.name} name or alias`);
1758
- }
1759
- // Set the remote entry to a complete path
1760
- if ('entry' in remote) {
1761
- if (sdk.isBrowserEnv() && !remote.entry.startsWith('http')) {
1762
- remote.entry = new URL(remote.entry, window.location.origin).href;
1763
- }
1764
- }
1765
- if (!remote.shareScope) {
1766
- remote.shareScope = share.DEFAULT_SCOPE;
1767
- }
1768
- if (!remote.type) {
1769
- remote.type = share.DEFAULT_REMOTE_TYPE;
1770
- }
1771
- };
1772
- this.hooks.lifecycle.beforeRegisterRemote.emit({
1773
- remote,
1774
- origin: host
1775
- });
1776
- const registeredRemote = targetRemotes.find((item)=>item.name === remote.name);
1777
- if (!registeredRemote) {
1778
- normalizeRemote();
1779
- targetRemotes.push(remote);
1780
- this.hooks.lifecycle.registerRemote.emit({
1781
- remote,
1782
- origin: host
1783
- });
1784
- } else {
1785
- const messages = [
1786
- `The remote "${remote.name}" is already registered.`,
1787
- 'Please note that overriding it may cause unexpected errors.'
1788
- ];
1789
- if (options == null ? void 0 : options.force) {
1790
- // remove registered remote
1791
- this.removeRemote(registeredRemote);
1792
- normalizeRemote();
1793
- targetRemotes.push(remote);
1794
- this.hooks.lifecycle.registerRemote.emit({
1795
- remote,
1796
- origin: host
1797
- });
1798
- sdk.warn(messages.join(' '));
1799
- }
1800
- }
1801
- }
1802
- removeRemote(remote) {
1803
- try {
1804
- const { host } = this;
1805
- const { name } = remote;
1806
- const remoteIndex = host.options.remotes.findIndex((item)=>item.name === name);
1807
- if (remoteIndex !== -1) {
1808
- host.options.remotes.splice(remoteIndex, 1);
1809
- }
1810
- const loadedModule = host.moduleCache.get(remote.name);
1811
- if (loadedModule) {
1812
- const remoteInfo = loadedModule.remoteInfo;
1813
- const key = remoteInfo.entryGlobalName;
1814
- if (share.CurrentGlobal[key]) {
1815
- var _Object_getOwnPropertyDescriptor;
1816
- if ((_Object_getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor(share.CurrentGlobal, key)) == null ? void 0 : _Object_getOwnPropertyDescriptor.configurable) {
1817
- delete share.CurrentGlobal[key];
1818
- } else {
1819
- // @ts-ignore
1820
- share.CurrentGlobal[key] = undefined;
1821
- }
1822
- }
1823
- const remoteEntryUniqueKey = getRemoteEntryUniqueKey(loadedModule.remoteInfo);
1824
- if (share.globalLoading[remoteEntryUniqueKey]) {
1825
- delete share.globalLoading[remoteEntryUniqueKey];
1826
- }
1827
- host.snapshotHandler.manifestCache.delete(remoteInfo.entry);
1828
- // delete unloaded shared and instance
1829
- let remoteInsId = remoteInfo.buildVersion ? sdk.composeKeyWithSeparator(remoteInfo.name, remoteInfo.buildVersion) : remoteInfo.name;
1830
- const remoteInsIndex = share.CurrentGlobal.__FEDERATION__.__INSTANCES__.findIndex((ins)=>{
1831
- if (remoteInfo.buildVersion) {
1832
- return ins.options.id === remoteInsId;
1833
- } else {
1834
- return ins.name === remoteInsId;
1835
- }
1836
- });
1837
- if (remoteInsIndex !== -1) {
1838
- const remoteIns = share.CurrentGlobal.__FEDERATION__.__INSTANCES__[remoteInsIndex];
1839
- remoteInsId = remoteIns.options.id || remoteInsId;
1840
- const globalShareScopeMap = share.getGlobalShareScope();
1841
- let isAllSharedNotUsed = true;
1842
- const needDeleteKeys = [];
1843
- Object.keys(globalShareScopeMap).forEach((instId)=>{
1844
- const shareScopeMap = globalShareScopeMap[instId];
1845
- shareScopeMap && Object.keys(shareScopeMap).forEach((shareScope)=>{
1846
- const shareScopeVal = shareScopeMap[shareScope];
1847
- shareScopeVal && Object.keys(shareScopeVal).forEach((shareName)=>{
1848
- const sharedPkgs = shareScopeVal[shareName];
1849
- sharedPkgs && Object.keys(sharedPkgs).forEach((shareVersion)=>{
1850
- const shared = sharedPkgs[shareVersion];
1851
- if (shared && typeof shared === 'object' && shared.from === remoteInfo.name) {
1852
- if (shared.loaded || shared.loading) {
1853
- shared.useIn = shared.useIn.filter((usedHostName)=>usedHostName !== remoteInfo.name);
1854
- if (shared.useIn.length) {
1855
- isAllSharedNotUsed = false;
1856
- } else {
1857
- needDeleteKeys.push([
1858
- instId,
1859
- shareScope,
1860
- shareName,
1861
- shareVersion
1862
- ]);
1863
- }
1864
- } else {
1865
- needDeleteKeys.push([
1866
- instId,
1867
- shareScope,
1868
- shareName,
1869
- shareVersion
1870
- ]);
1871
- }
1872
- }
1873
- });
1874
- });
1875
- });
1876
- });
1877
- if (isAllSharedNotUsed) {
1878
- remoteIns.shareScopeMap = {};
1879
- delete globalShareScopeMap[remoteInsId];
1880
- }
1881
- needDeleteKeys.forEach(([insId, shareScope, shareName, shareVersion])=>{
1882
- var _globalShareScopeMap_insId_shareScope_shareName, _globalShareScopeMap_insId_shareScope, _globalShareScopeMap_insId;
1883
- (_globalShareScopeMap_insId = globalShareScopeMap[insId]) == null ? true : (_globalShareScopeMap_insId_shareScope = _globalShareScopeMap_insId[shareScope]) == null ? true : (_globalShareScopeMap_insId_shareScope_shareName = _globalShareScopeMap_insId_shareScope[shareName]) == null ? true : delete _globalShareScopeMap_insId_shareScope_shareName[shareVersion];
1884
- });
1885
- share.CurrentGlobal.__FEDERATION__.__INSTANCES__.splice(remoteInsIndex, 1);
1886
- }
1887
- const { hostGlobalSnapshot } = getGlobalRemoteInfo(remote, host);
1888
- if (hostGlobalSnapshot) {
1889
- const remoteKey = hostGlobalSnapshot && 'remotesInfo' in hostGlobalSnapshot && hostGlobalSnapshot.remotesInfo && share.getInfoWithoutType(hostGlobalSnapshot.remotesInfo, remote.name).key;
1890
- if (remoteKey) {
1891
- delete hostGlobalSnapshot.remotesInfo[remoteKey];
1892
- if (//eslint-disable-next-line no-extra-boolean-cast
1893
- Boolean(share.Global.__FEDERATION__.__MANIFEST_LOADING__[remoteKey])) {
1894
- delete share.Global.__FEDERATION__.__MANIFEST_LOADING__[remoteKey];
1895
- }
1896
- }
1897
- }
1898
- host.moduleCache.delete(remote.name);
1899
- }
1900
- } catch (err) {
1901
- share.logger.log('removeRemote fail: ', err);
1902
- }
1903
- }
1904
- constructor(host){
1905
- this.hooks = new PluginSystem({
1906
- beforeRegisterRemote: new SyncWaterfallHook('beforeRegisterRemote'),
1907
- registerRemote: new SyncWaterfallHook('registerRemote'),
1908
- beforeRequest: new AsyncWaterfallHook('beforeRequest'),
1909
- onLoad: new AsyncHook('onLoad'),
1910
- handlePreloadModule: new SyncHook('handlePreloadModule'),
1911
- errorLoadRemote: new AsyncHook('errorLoadRemote'),
1912
- beforePreloadRemote: new AsyncHook('beforePreloadRemote'),
1913
- generatePreloadAssets: new AsyncHook('generatePreloadAssets'),
1914
- // not used yet
1915
- afterPreloadRemote: new AsyncHook(),
1916
- loadEntry: new AsyncHook()
1917
- });
1918
- this.host = host;
1919
- this.idToRemoteMap = {};
1920
- }
1921
- }
1922
-
1923
- class FederationHost {
1924
- initOptions(userOptions) {
1925
- this.registerPlugins(userOptions.plugins);
1926
- const options = this.formatOptions(this.options, userOptions);
1927
- this.options = options;
1928
- return options;
1929
- }
1930
- async loadShare(pkgName, extraOptions) {
1931
- return this.sharedHandler.loadShare(pkgName, extraOptions);
1932
- }
1933
- // The lib function will only be available if the shared set by eager or runtime init is set or the shared is successfully loaded.
1934
- // 1. If the loaded shared already exists globally, then it will be reused
1935
- // 2. If lib exists in local shared, it will be used directly
1936
- // 3. If the local get returns something other than Promise, then it will be used directly
1937
- loadShareSync(pkgName, extraOptions) {
1938
- return this.sharedHandler.loadShareSync(pkgName, extraOptions);
1939
- }
1940
- initializeSharing(shareScopeName = share.DEFAULT_SCOPE, extraOptions) {
1941
- return this.sharedHandler.initializeSharing(shareScopeName, extraOptions);
1942
- }
1943
- initRawContainer(name, url, container) {
1944
- const remoteInfo = getRemoteInfo({
1945
- name,
1946
- entry: url
1947
- });
1948
- const module = new Module({
1949
- host: this,
1950
- remoteInfo
1951
- });
1952
- module.remoteEntryExports = container;
1953
- this.moduleCache.set(name, module);
1954
- return module;
1955
- }
1956
- // eslint-disable-next-line max-lines-per-function
1957
- // eslint-disable-next-line @typescript-eslint/member-ordering
1958
- async loadRemote(id, options) {
1959
- return this.remoteHandler.loadRemote(id, options);
1960
- }
1961
- // eslint-disable-next-line @typescript-eslint/member-ordering
1962
- async preloadRemote(preloadOptions) {
1963
- return this.remoteHandler.preloadRemote(preloadOptions);
1964
- }
1965
- initShareScopeMap(scopeName, shareScope, extraOptions = {}) {
1966
- this.sharedHandler.initShareScopeMap(scopeName, shareScope, extraOptions);
1967
- }
1968
- formatOptions(globalOptions, userOptions) {
1969
- const { shared } = share.formatShareConfigs(globalOptions, userOptions);
1970
- const { userOptions: userOptionsRes, options: globalOptionsRes } = this.hooks.lifecycle.beforeInit.emit({
1971
- origin: this,
1972
- userOptions,
1973
- options: globalOptions,
1974
- shareInfo: shared
1975
- });
1976
- const remotes = this.remoteHandler.formatAndRegisterRemote(globalOptionsRes, userOptionsRes);
1977
- const { shared: handledShared } = this.sharedHandler.registerShared(globalOptionsRes, userOptionsRes);
1978
- const plugins = [
1979
- ...globalOptionsRes.plugins
1980
- ];
1981
- if (userOptionsRes.plugins) {
1982
- userOptionsRes.plugins.forEach((plugin)=>{
1983
- if (!plugins.includes(plugin)) {
1984
- plugins.push(plugin);
1985
- }
1986
- });
1987
- }
1988
- const optionsRes = polyfills._extends({}, globalOptions, userOptions, {
1989
- plugins,
1990
- remotes,
1991
- shared: handledShared
1992
- });
1993
- this.hooks.lifecycle.init.emit({
1994
- origin: this,
1995
- options: optionsRes
1996
- });
1997
- return optionsRes;
1998
- }
1999
- registerPlugins(plugins) {
2000
- const pluginRes = registerPlugins$1(plugins, [
2001
- this.hooks,
2002
- this.remoteHandler.hooks,
2003
- this.sharedHandler.hooks,
2004
- this.snapshotHandler.hooks,
2005
- this.loaderHook,
2006
- this.bridgeHook
2007
- ]);
2008
- // Merge plugin
2009
- this.options.plugins = this.options.plugins.reduce((res, plugin)=>{
2010
- if (!plugin) return res;
2011
- if (res && !res.find((item)=>item.name === plugin.name)) {
2012
- res.push(plugin);
2013
- }
2014
- return res;
2015
- }, pluginRes || []);
2016
- }
2017
- registerRemotes(remotes, options) {
2018
- return this.remoteHandler.registerRemotes(remotes, options);
2019
- }
2020
- constructor(userOptions){
2021
- this.hooks = new PluginSystem({
2022
- beforeInit: new SyncWaterfallHook('beforeInit'),
2023
- init: new SyncHook(),
2024
- // maybe will change, temporarily for internal use only
2025
- beforeInitContainer: new AsyncWaterfallHook('beforeInitContainer'),
2026
- // maybe will change, temporarily for internal use only
2027
- initContainer: new AsyncWaterfallHook('initContainer')
2028
- });
2029
- this.version = "0.8.6";
2030
- this.moduleCache = new Map();
2031
- this.loaderHook = new PluginSystem({
2032
- // FIXME: may not be suitable , not open to the public yet
2033
- getModuleInfo: new SyncHook(),
2034
- createScript: new SyncHook(),
2035
- createLink: new SyncHook(),
2036
- fetch: new AsyncHook(),
2037
- loadEntryError: new AsyncHook(),
2038
- getModuleFactory: new AsyncHook()
2039
- });
2040
- this.bridgeHook = new PluginSystem({
2041
- beforeBridgeRender: new SyncHook(),
2042
- afterBridgeRender: new SyncHook(),
2043
- beforeBridgeDestroy: new SyncHook(),
2044
- afterBridgeDestroy: new SyncHook()
2045
- });
2046
- // TODO: Validate the details of the options
2047
- // Initialize options with default values
2048
- const defaultOptions = {
2049
- id: share.getBuilderId(),
2050
- name: userOptions.name,
2051
- plugins: [
2052
- snapshotPlugin(),
2053
- generatePreloadAssetsPlugin()
2054
- ],
2055
- remotes: [],
2056
- shared: {},
2057
- inBrowser: sdk.isBrowserEnv()
2058
- };
2059
- this.name = userOptions.name;
2060
- this.options = defaultOptions;
2061
- this.snapshotHandler = new SnapshotHandler(this);
2062
- this.sharedHandler = new SharedHandler(this);
2063
- this.remoteHandler = new RemoteHandler(this);
2064
- this.shareScopeMap = this.sharedHandler.shareScopeMap;
2065
- this.registerPlugins([
2066
- ...defaultOptions.plugins,
2067
- ...userOptions.plugins || []
2068
- ]);
2069
- this.options = this.formatOptions(defaultOptions, userOptions);
2070
- }
2071
- }
3
+ var runtimeCore = require('@module-federation/runtime-core');
4
+ var utils = require('./utils.cjs.js');
2072
5
 
2073
6
  let FederationInstance = null;
2074
7
  function init(options) {
2075
8
  // Retrieve the same instance with the same name
2076
- const instance = share.getGlobalFederationInstance(options.name, options.version);
9
+ const instance = utils.getGlobalFederationInstance(options.name, options.version);
2077
10
  if (!instance) {
2078
11
  // Retrieve debug constructor
2079
- const FederationConstructor = share.getGlobalFederationConstructor() || FederationHost;
12
+ const FederationConstructor = runtimeCore.getGlobalFederationConstructor() || runtimeCore.FederationHost;
2080
13
  FederationInstance = new FederationConstructor(options);
2081
- share.setGlobalFederationInstance(FederationInstance);
14
+ runtimeCore.setGlobalFederationInstance(FederationInstance);
2082
15
  return FederationInstance;
2083
16
  } else {
2084
17
  // Merge options
@@ -2090,35 +23,35 @@ function init(options) {
2090
23
  }
2091
24
  }
2092
25
  function loadRemote(...args) {
2093
- share.assert(FederationInstance, 'Please call init first');
26
+ runtimeCore.assert(FederationInstance, 'Please call init first');
2094
27
  const loadRemote1 = FederationInstance.loadRemote;
2095
28
  // eslint-disable-next-line prefer-spread
2096
29
  return loadRemote1.apply(FederationInstance, args);
2097
30
  }
2098
31
  function loadShare(...args) {
2099
- share.assert(FederationInstance, 'Please call init first');
32
+ runtimeCore.assert(FederationInstance, 'Please call init first');
2100
33
  // eslint-disable-next-line prefer-spread
2101
34
  const loadShare1 = FederationInstance.loadShare;
2102
35
  return loadShare1.apply(FederationInstance, args);
2103
36
  }
2104
37
  function loadShareSync(...args) {
2105
- share.assert(FederationInstance, 'Please call init first');
38
+ runtimeCore.assert(FederationInstance, 'Please call init first');
2106
39
  const loadShareSync1 = FederationInstance.loadShareSync;
2107
40
  // eslint-disable-next-line prefer-spread
2108
41
  return loadShareSync1.apply(FederationInstance, args);
2109
42
  }
2110
43
  function preloadRemote(...args) {
2111
- share.assert(FederationInstance, 'Please call init first');
44
+ runtimeCore.assert(FederationInstance, 'Please call init first');
2112
45
  // eslint-disable-next-line prefer-spread
2113
46
  return FederationInstance.preloadRemote.apply(FederationInstance, args);
2114
47
  }
2115
48
  function registerRemotes(...args) {
2116
- share.assert(FederationInstance, 'Please call init first');
49
+ runtimeCore.assert(FederationInstance, 'Please call init first');
2117
50
  // eslint-disable-next-line prefer-spread
2118
51
  return FederationInstance.registerRemotes.apply(FederationInstance, args);
2119
52
  }
2120
53
  function registerPlugins(...args) {
2121
- share.assert(FederationInstance, 'Please call init first');
54
+ runtimeCore.assert(FederationInstance, 'Please call init first');
2122
55
  // eslint-disable-next-line prefer-spread
2123
56
  return FederationInstance.registerPlugins.apply(FederationInstance, args);
2124
57
  }
@@ -2126,22 +59,37 @@ function getInstance() {
2126
59
  return FederationInstance;
2127
60
  }
2128
61
  // Inject for debug
2129
- share.setGlobalFederationConstructor(FederationHost);
62
+ runtimeCore.setGlobalFederationConstructor(runtimeCore.FederationHost);
2130
63
 
64
+ Object.defineProperty(exports, "FederationHost", {
65
+ enumerable: true,
66
+ get: function () { return runtimeCore.FederationHost; }
67
+ });
68
+ Object.defineProperty(exports, "Module", {
69
+ enumerable: true,
70
+ get: function () { return runtimeCore.Module; }
71
+ });
72
+ Object.defineProperty(exports, "getRemoteEntry", {
73
+ enumerable: true,
74
+ get: function () { return runtimeCore.getRemoteEntry; }
75
+ });
76
+ Object.defineProperty(exports, "getRemoteInfo", {
77
+ enumerable: true,
78
+ get: function () { return runtimeCore.getRemoteInfo; }
79
+ });
2131
80
  Object.defineProperty(exports, "loadScript", {
2132
81
  enumerable: true,
2133
- get: function () { return sdk.loadScript; }
82
+ get: function () { return runtimeCore.loadScript; }
2134
83
  });
2135
84
  Object.defineProperty(exports, "loadScriptNode", {
2136
85
  enumerable: true,
2137
- get: function () { return sdk.loadScriptNode; }
86
+ get: function () { return runtimeCore.loadScriptNode; }
87
+ });
88
+ Object.defineProperty(exports, "registerGlobalPlugins", {
89
+ enumerable: true,
90
+ get: function () { return runtimeCore.registerGlobalPlugins; }
2138
91
  });
2139
- exports.registerGlobalPlugins = share.registerGlobalPlugins;
2140
- exports.FederationHost = FederationHost;
2141
- exports.Module = Module;
2142
92
  exports.getInstance = getInstance;
2143
- exports.getRemoteEntry = getRemoteEntry;
2144
- exports.getRemoteInfo = getRemoteInfo;
2145
93
  exports.init = init;
2146
94
  exports.loadRemote = loadRemote;
2147
95
  exports.loadShare = loadShare;