@module-federation/runtime-core 2.3.2 → 2.4.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/dist/core.cjs CHANGED
@@ -30,7 +30,7 @@ var ModuleFederation = class {
30
30
  beforeInitContainer: new require_asyncWaterfallHooks.AsyncWaterfallHook("beforeInitContainer"),
31
31
  initContainer: new require_asyncWaterfallHooks.AsyncWaterfallHook("initContainer")
32
32
  });
33
- this.version = "2.3.2";
33
+ this.version = "2.4.0";
34
34
  this.moduleCache = /* @__PURE__ */ new Map();
35
35
  this.loaderHook = new require_pluginSystem.PluginSystem({
36
36
  getModuleInfo: new require_syncHook.SyncHook(),
@@ -121,7 +121,8 @@ var ModuleFederation = class {
121
121
  ...userOptions,
122
122
  plugins,
123
123
  remotes,
124
- shared: allShareInfos
124
+ shared: allShareInfos,
125
+ id: userOptionsRes.id || globalOptions.id
125
126
  };
126
127
  this.hooks.lifecycle.init.emit({
127
128
  origin: this,
package/dist/core.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"core.cjs","names":["PluginSystem","SyncWaterfallHook","SyncHook","AsyncWaterfallHook","AsyncHook","snapshotPlugin","generatePreloadAssetsPlugin","getBuilderId","isBrowserEnvValue","SnapshotHandler","SharedHandler","RemoteHandler","RUNTIME_010","runtimeDescMap","DEFAULT_SCOPE","getRemoteInfo","Module","formatShareConfigs","registerPlugins"],"sources":["../src/core.ts"],"sourcesContent":["import { isBrowserEnvValue } from '@module-federation/sdk';\nimport type {\n CreateScriptHookReturn,\n GlobalModuleInfo,\n ModuleInfo,\n} from '@module-federation/sdk';\nimport {\n Options,\n PreloadRemoteArgs,\n RemoteEntryExports,\n Remote,\n Shared,\n ShareInfos,\n UserOptions,\n RemoteInfo,\n ShareScopeMap,\n InitScope,\n RemoteEntryInitOptions,\n CallFrom,\n} from './type';\nimport { getBuilderId, registerPlugins, getRemoteEntry, error } from './utils';\nimport {\n getShortErrorMsg,\n RUNTIME_010,\n runtimeDescMap,\n} from '@module-federation/error-codes';\nimport { Module } from './module';\nimport {\n AsyncHook,\n AsyncWaterfallHook,\n PluginSystem,\n SyncHook,\n SyncWaterfallHook,\n} from './utils/hooks';\nimport { generatePreloadAssetsPlugin } from './plugins/generate-preload-assets';\nimport { snapshotPlugin } from './plugins/snapshot';\nimport { getRemoteInfo } from './utils/load';\nimport { DEFAULT_SCOPE } from './constant';\nimport { SnapshotHandler } from './plugins/snapshot/SnapshotHandler';\nimport { SharedHandler } from './shared';\nimport { RemoteHandler } from './remote';\nimport { formatShareConfigs } from './utils/share';\n\n// Declare the global constant that will be defined by DefinePlugin\n// Default to true if not defined (e.g., when runtime-core is used outside of webpack)\n// so that snapshot functionality is included by default.\ndeclare const FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN: boolean;\nconst USE_SNAPSHOT =\n typeof FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN === 'boolean'\n ? !FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN\n : true; // Default to true (use snapshot) when not explicitly defined\n\nexport class ModuleFederation {\n options: Options;\n hooks = new PluginSystem({\n beforeInit: new SyncWaterfallHook<{\n userOptions: UserOptions;\n options: Options;\n origin: ModuleFederation;\n /**\n * @deprecated shareInfo will be removed soon, please use userOptions directly!\n */\n shareInfo: ShareInfos;\n }>('beforeInit'),\n init: new SyncHook<\n [\n {\n options: Options;\n origin: ModuleFederation;\n },\n ],\n void\n >(),\n // maybe will change, temporarily for internal use only\n beforeInitContainer: new AsyncWaterfallHook<{\n shareScope: ShareScopeMap[string];\n initScope: InitScope;\n remoteEntryInitOptions: RemoteEntryInitOptions;\n remoteInfo: RemoteInfo;\n origin: ModuleFederation;\n }>('beforeInitContainer'),\n // maybe will change, temporarily for internal use only\n initContainer: new AsyncWaterfallHook<{\n shareScope: ShareScopeMap[string];\n initScope: InitScope;\n remoteEntryInitOptions: RemoteEntryInitOptions;\n remoteInfo: RemoteInfo;\n remoteEntryExports: RemoteEntryExports;\n origin: ModuleFederation;\n id?: string;\n remoteSnapshot?: ModuleInfo;\n }>('initContainer'),\n });\n version: string = __VERSION__;\n name: string;\n moduleCache: Map<string, Module> = new Map();\n snapshotHandler: SnapshotHandler;\n sharedHandler: SharedHandler;\n remoteHandler: RemoteHandler;\n shareScopeMap: ShareScopeMap;\n loaderHook = new PluginSystem({\n // FIXME: may not be suitable , not open to the public yet\n getModuleInfo: new SyncHook<\n [\n {\n target: Record<string, any>;\n key: any;\n },\n ],\n { value: any | undefined; key: string } | void\n >(),\n createScript: new SyncHook<\n [\n {\n url: string;\n attrs?: Record<string, any>;\n },\n ],\n CreateScriptHookReturn\n >(),\n createLink: new SyncHook<\n [\n {\n url: string;\n attrs?: Record<string, any>;\n },\n ],\n HTMLLinkElement | void\n >(),\n fetch: new AsyncHook<\n [string, RequestInit],\n Promise<Response> | void | false\n >(),\n loadEntryError: new AsyncHook<\n [\n {\n getRemoteEntry: typeof getRemoteEntry;\n origin: ModuleFederation;\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports | undefined;\n globalLoading: Record<\n string,\n Promise<void | RemoteEntryExports> | undefined\n >;\n uniqueKey: string;\n },\n ],\n Promise<Promise<RemoteEntryExports | undefined> | undefined>\n >(),\n getModuleFactory: new AsyncHook<\n [\n {\n remoteEntryExports: RemoteEntryExports;\n expose: string;\n moduleInfo: RemoteInfo;\n },\n ],\n Promise<(() => Promise<Module>) | undefined>\n >(),\n });\n bridgeHook = new PluginSystem({\n beforeBridgeRender: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n afterBridgeRender: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n beforeBridgeDestroy: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n afterBridgeDestroy: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n });\n moduleInfo?: GlobalModuleInfo[string];\n\n constructor(userOptions: UserOptions) {\n const plugins = USE_SNAPSHOT\n ? [snapshotPlugin(), generatePreloadAssetsPlugin()]\n : [];\n // TODO: Validate the details of the options\n // Initialize options with default values\n const defaultOptions: Options = {\n id: getBuilderId(),\n name: userOptions.name,\n plugins,\n remotes: [],\n shared: {},\n inBrowser: isBrowserEnvValue,\n };\n\n this.name = userOptions.name;\n this.options = defaultOptions;\n this.snapshotHandler = new SnapshotHandler(this);\n this.sharedHandler = new SharedHandler(this);\n this.remoteHandler = new RemoteHandler(this);\n this.shareScopeMap = this.sharedHandler.shareScopeMap;\n this.registerPlugins([\n ...defaultOptions.plugins,\n ...(userOptions.plugins || []),\n ]);\n this.options = this.formatOptions(defaultOptions, userOptions);\n }\n\n initOptions(userOptions: UserOptions): Options {\n if (userOptions.name && userOptions.name !== this.options.name) {\n error(getShortErrorMsg(RUNTIME_010, runtimeDescMap));\n }\n this.registerPlugins(userOptions.plugins);\n const options = this.formatOptions(this.options, userOptions);\n\n this.options = options;\n\n return options;\n }\n\n async loadShare<T>(\n pkgName: string,\n extraOptions?: {\n customShareInfo?: Partial<Shared>;\n resolver?: (sharedOptions: ShareInfos[string]) => Shared;\n },\n ): Promise<false | (() => T | undefined)> {\n return this.sharedHandler.loadShare(pkgName, extraOptions);\n }\n\n // The lib function will only be available if the shared set by eager or runtime init is set or the shared is successfully loaded.\n // 1. If the loaded shared already exists globally, then it will be reused\n // 2. If lib exists in local shared, it will be used directly\n // 3. If the local get returns something other than Promise, then it will be used directly\n loadShareSync<T>(\n pkgName: string,\n extraOptions?: {\n customShareInfo?: Partial<Shared>;\n from?: 'build' | 'runtime';\n resolver?: (sharedOptions: ShareInfos[string]) => Shared;\n },\n ): () => T | never {\n return this.sharedHandler.loadShareSync(pkgName, extraOptions);\n }\n\n initializeSharing(\n shareScopeName = DEFAULT_SCOPE,\n extraOptions?: {\n initScope?: InitScope;\n from?: CallFrom;\n strategy?: Shared['strategy'];\n },\n ): Array<Promise<void>> {\n return this.sharedHandler.initializeSharing(shareScopeName, extraOptions);\n }\n\n initRawContainer(\n name: string,\n url: string,\n container: RemoteEntryExports,\n ): Module {\n const remoteInfo = getRemoteInfo({ name, entry: url });\n const module = new Module({ host: this, remoteInfo });\n\n module.remoteEntryExports = container;\n this.moduleCache.set(name, module);\n\n return module;\n }\n\n // eslint-disable-next-line max-lines-per-function\n // eslint-disable-next-line @typescript-eslint/member-ordering\n async loadRemote<T>(\n id: string,\n options?: { loadFactory?: boolean; from: CallFrom },\n ): Promise<T | null> {\n return this.remoteHandler.loadRemote(id, options);\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n async preloadRemote(preloadOptions: Array<PreloadRemoteArgs>): Promise<void> {\n return this.remoteHandler.preloadRemote(preloadOptions);\n }\n\n initShareScopeMap(\n scopeName: string,\n shareScope: ShareScopeMap[string],\n extraOptions: { hostShareScopeMap?: ShareScopeMap } = {},\n ): void {\n this.sharedHandler.initShareScopeMap(scopeName, shareScope, extraOptions);\n }\n\n formatOptions(globalOptions: Options, userOptions: UserOptions): Options {\n const { allShareInfos: shared } = formatShareConfigs(\n globalOptions,\n userOptions,\n );\n const { userOptions: userOptionsRes, options: globalOptionsRes } =\n this.hooks.lifecycle.beforeInit.emit({\n origin: this,\n userOptions,\n options: globalOptions,\n shareInfo: shared,\n });\n\n const remotes = this.remoteHandler.formatAndRegisterRemote(\n globalOptionsRes,\n userOptionsRes,\n );\n\n const { allShareInfos } = this.sharedHandler.registerShared(\n globalOptionsRes,\n userOptionsRes,\n );\n\n const plugins = [...globalOptionsRes.plugins];\n\n if (userOptionsRes.plugins) {\n userOptionsRes.plugins.forEach((plugin) => {\n if (!plugins.includes(plugin)) {\n plugins.push(plugin);\n }\n });\n }\n\n const optionsRes: Options = {\n ...globalOptions,\n ...userOptions,\n plugins,\n remotes,\n shared: allShareInfos,\n };\n\n this.hooks.lifecycle.init.emit({\n origin: this,\n options: optionsRes,\n });\n return optionsRes;\n }\n\n registerPlugins(plugins: UserOptions['plugins']) {\n const pluginRes = registerPlugins(plugins, this);\n // Merge plugin\n this.options.plugins = this.options.plugins.reduce((res, plugin) => {\n if (!plugin) return res;\n if (res && !res.find((item) => item.name === plugin.name)) {\n res.push(plugin);\n }\n return res;\n }, pluginRes || []);\n }\n registerRemotes(remotes: Remote[], options?: { force?: boolean }): void {\n return this.remoteHandler.registerRemotes(remotes, options);\n }\n\n registerShared(shared: UserOptions['shared']) {\n this.sharedHandler.registerShared(this.options, {\n ...this.options,\n shared,\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"core.cjs","names":["PluginSystem","SyncWaterfallHook","SyncHook","AsyncWaterfallHook","AsyncHook","snapshotPlugin","generatePreloadAssetsPlugin","getBuilderId","isBrowserEnvValue","SnapshotHandler","SharedHandler","RemoteHandler","RUNTIME_010","runtimeDescMap","DEFAULT_SCOPE","getRemoteInfo","Module","formatShareConfigs","registerPlugins"],"sources":["../src/core.ts"],"sourcesContent":["import { isBrowserEnvValue } from '@module-federation/sdk';\nimport type {\n CreateScriptHookReturn,\n GlobalModuleInfo,\n ModuleInfo,\n} from '@module-federation/sdk';\nimport {\n Options,\n PreloadRemoteArgs,\n RemoteEntryExports,\n Remote,\n Shared,\n ShareInfos,\n UserOptions,\n RemoteInfo,\n ShareScopeMap,\n InitScope,\n RemoteEntryInitOptions,\n CallFrom,\n} from './type';\nimport { getBuilderId, registerPlugins, getRemoteEntry, error } from './utils';\nimport {\n getShortErrorMsg,\n RUNTIME_010,\n runtimeDescMap,\n} from '@module-federation/error-codes';\nimport { Module } from './module';\nimport {\n AsyncHook,\n AsyncWaterfallHook,\n PluginSystem,\n SyncHook,\n SyncWaterfallHook,\n} from './utils/hooks';\nimport { generatePreloadAssetsPlugin } from './plugins/generate-preload-assets';\nimport { snapshotPlugin } from './plugins/snapshot';\nimport { getRemoteInfo } from './utils/load';\nimport { DEFAULT_SCOPE } from './constant';\nimport { SnapshotHandler } from './plugins/snapshot/SnapshotHandler';\nimport { SharedHandler } from './shared';\nimport { RemoteHandler } from './remote';\nimport { formatShareConfigs } from './utils/share';\n\n// Declare the global constant that will be defined by DefinePlugin\n// Default to true if not defined (e.g., when runtime-core is used outside of webpack)\n// so that snapshot functionality is included by default.\ndeclare const FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN: boolean;\nconst USE_SNAPSHOT =\n typeof FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN === 'boolean'\n ? !FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN\n : true; // Default to true (use snapshot) when not explicitly defined\n\nexport class ModuleFederation {\n options: Options;\n hooks = new PluginSystem({\n beforeInit: new SyncWaterfallHook<{\n userOptions: UserOptions;\n options: Options;\n origin: ModuleFederation;\n /**\n * @deprecated shareInfo will be removed soon, please use userOptions directly!\n */\n shareInfo: ShareInfos;\n }>('beforeInit'),\n init: new SyncHook<\n [\n {\n options: Options;\n origin: ModuleFederation;\n },\n ],\n void\n >(),\n // maybe will change, temporarily for internal use only\n beforeInitContainer: new AsyncWaterfallHook<{\n shareScope: ShareScopeMap[string];\n initScope: InitScope;\n remoteEntryInitOptions: RemoteEntryInitOptions;\n remoteInfo: RemoteInfo;\n origin: ModuleFederation;\n }>('beforeInitContainer'),\n // maybe will change, temporarily for internal use only\n initContainer: new AsyncWaterfallHook<{\n shareScope: ShareScopeMap[string];\n initScope: InitScope;\n remoteEntryInitOptions: RemoteEntryInitOptions;\n remoteInfo: RemoteInfo;\n remoteEntryExports: RemoteEntryExports;\n origin: ModuleFederation;\n id?: string;\n remoteSnapshot?: ModuleInfo;\n }>('initContainer'),\n });\n version: string = __VERSION__;\n name: string;\n moduleCache: Map<string, Module> = new Map();\n snapshotHandler: SnapshotHandler;\n sharedHandler: SharedHandler;\n remoteHandler: RemoteHandler;\n shareScopeMap: ShareScopeMap;\n loaderHook = new PluginSystem({\n // FIXME: may not be suitable , not open to the public yet\n getModuleInfo: new SyncHook<\n [\n {\n target: Record<string, any>;\n key: any;\n },\n ],\n { value: any | undefined; key: string } | void\n >(),\n createScript: new SyncHook<\n [\n {\n url: string;\n attrs?: Record<string, any>;\n /**\n * The producer(remote) info bound to this resource.\n * Only present when the loader is invoked in a remote-related context\n * (e.g. preloadRemote / loading remoteEntry).\n */\n remoteInfo?: RemoteInfo;\n },\n ],\n CreateScriptHookReturn\n >(),\n createLink: new SyncHook<\n [\n {\n url: string;\n attrs?: Record<string, any>;\n /**\n * The producer(remote) info bound to this resource.\n * Only present when the loader is invoked in a remote-related context\n * (e.g. preloadRemote / loading remoteEntry).\n */\n remoteInfo?: RemoteInfo;\n },\n ],\n HTMLLinkElement | void\n >(),\n fetch: new AsyncHook<\n [string, RequestInit, RemoteInfo?],\n Promise<Response> | void | false\n >(),\n loadEntryError: new AsyncHook<\n [\n {\n getRemoteEntry: typeof getRemoteEntry;\n origin: ModuleFederation;\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports | undefined;\n globalLoading: Record<\n string,\n Promise<void | RemoteEntryExports> | undefined\n >;\n uniqueKey: string;\n },\n ],\n Promise<Promise<RemoteEntryExports | undefined> | undefined>\n >(),\n getModuleFactory: new AsyncHook<\n [\n {\n remoteEntryExports: RemoteEntryExports;\n expose: string;\n moduleInfo: RemoteInfo;\n },\n ],\n Promise<(() => Promise<Module>) | undefined>\n >(),\n });\n bridgeHook = new PluginSystem({\n beforeBridgeRender: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n afterBridgeRender: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n beforeBridgeDestroy: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n afterBridgeDestroy: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n });\n moduleInfo?: GlobalModuleInfo[string];\n\n constructor(userOptions: UserOptions) {\n const plugins = USE_SNAPSHOT\n ? [snapshotPlugin(), generatePreloadAssetsPlugin()]\n : [];\n // TODO: Validate the details of the options\n // Initialize options with default values\n const defaultOptions: Options = {\n id: getBuilderId(),\n name: userOptions.name,\n plugins,\n remotes: [],\n shared: {},\n inBrowser: isBrowserEnvValue,\n };\n\n this.name = userOptions.name;\n this.options = defaultOptions;\n this.snapshotHandler = new SnapshotHandler(this);\n this.sharedHandler = new SharedHandler(this);\n this.remoteHandler = new RemoteHandler(this);\n this.shareScopeMap = this.sharedHandler.shareScopeMap;\n this.registerPlugins([\n ...defaultOptions.plugins,\n ...(userOptions.plugins || []),\n ]);\n this.options = this.formatOptions(defaultOptions, userOptions);\n }\n\n initOptions(userOptions: UserOptions): Options {\n if (userOptions.name && userOptions.name !== this.options.name) {\n error(getShortErrorMsg(RUNTIME_010, runtimeDescMap));\n }\n this.registerPlugins(userOptions.plugins);\n const options = this.formatOptions(this.options, userOptions);\n\n this.options = options;\n\n return options;\n }\n\n async loadShare<T>(\n pkgName: string,\n extraOptions?: {\n customShareInfo?: Partial<Shared>;\n resolver?: (sharedOptions: ShareInfos[string]) => Shared;\n },\n ): Promise<false | (() => T | undefined)> {\n return this.sharedHandler.loadShare(pkgName, extraOptions);\n }\n\n // The lib function will only be available if the shared set by eager or runtime init is set or the shared is successfully loaded.\n // 1. If the loaded shared already exists globally, then it will be reused\n // 2. If lib exists in local shared, it will be used directly\n // 3. If the local get returns something other than Promise, then it will be used directly\n loadShareSync<T>(\n pkgName: string,\n extraOptions?: {\n customShareInfo?: Partial<Shared>;\n from?: 'build' | 'runtime';\n resolver?: (sharedOptions: ShareInfos[string]) => Shared;\n },\n ): () => T | never {\n return this.sharedHandler.loadShareSync(pkgName, extraOptions);\n }\n\n initializeSharing(\n shareScopeName = DEFAULT_SCOPE,\n extraOptions?: {\n initScope?: InitScope;\n from?: CallFrom;\n strategy?: Shared['strategy'];\n },\n ): Array<Promise<void>> {\n return this.sharedHandler.initializeSharing(shareScopeName, extraOptions);\n }\n\n initRawContainer(\n name: string,\n url: string,\n container: RemoteEntryExports,\n ): Module {\n const remoteInfo = getRemoteInfo({ name, entry: url });\n const module = new Module({ host: this, remoteInfo });\n\n module.remoteEntryExports = container;\n this.moduleCache.set(name, module);\n\n return module;\n }\n\n // eslint-disable-next-line max-lines-per-function\n // eslint-disable-next-line @typescript-eslint/member-ordering\n async loadRemote<T>(\n id: string,\n options?: { loadFactory?: boolean; from: CallFrom },\n ): Promise<T | null> {\n return this.remoteHandler.loadRemote(id, options);\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n async preloadRemote(preloadOptions: Array<PreloadRemoteArgs>): Promise<void> {\n return this.remoteHandler.preloadRemote(preloadOptions);\n }\n\n initShareScopeMap(\n scopeName: string,\n shareScope: ShareScopeMap[string],\n extraOptions: { hostShareScopeMap?: ShareScopeMap } = {},\n ): void {\n this.sharedHandler.initShareScopeMap(scopeName, shareScope, extraOptions);\n }\n\n formatOptions(globalOptions: Options, userOptions: UserOptions): Options {\n const { allShareInfos: shared } = formatShareConfigs(\n globalOptions,\n userOptions,\n );\n const { userOptions: userOptionsRes, options: globalOptionsRes } =\n this.hooks.lifecycle.beforeInit.emit({\n origin: this,\n userOptions,\n options: globalOptions,\n shareInfo: shared,\n });\n\n const remotes = this.remoteHandler.formatAndRegisterRemote(\n globalOptionsRes,\n userOptionsRes,\n );\n\n const { allShareInfos } = this.sharedHandler.registerShared(\n globalOptionsRes,\n userOptionsRes,\n );\n\n const plugins = [...globalOptionsRes.plugins];\n\n if (userOptionsRes.plugins) {\n userOptionsRes.plugins.forEach((plugin) => {\n if (!plugins.includes(plugin)) {\n plugins.push(plugin);\n }\n });\n }\n\n const optionsRes: Options = {\n ...globalOptions,\n ...userOptions,\n plugins,\n remotes,\n shared: allShareInfos,\n id: userOptionsRes.id || globalOptions.id,\n };\n\n this.hooks.lifecycle.init.emit({\n origin: this,\n options: optionsRes,\n });\n return optionsRes;\n }\n\n registerPlugins(plugins: UserOptions['plugins']) {\n const pluginRes = registerPlugins(plugins, this);\n // Merge plugin\n this.options.plugins = this.options.plugins.reduce((res, plugin) => {\n if (!plugin) return res;\n if (res && !res.find((item) => item.name === plugin.name)) {\n res.push(plugin);\n }\n return res;\n }, pluginRes || []);\n }\n registerRemotes(remotes: Remote[], options?: { force?: boolean }): void {\n return this.remoteHandler.registerRemotes(remotes, options);\n }\n\n registerShared(shared: UserOptions['shared']) {\n this.sharedHandler.registerShared(this.options, {\n ...this.options,\n shared,\n });\n }\n}\n"],"mappings":"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"}
package/dist/core.d.ts CHANGED
@@ -65,12 +65,24 @@ declare class ModuleFederation {
65
65
  createScript: SyncHook<[{
66
66
  url: string;
67
67
  attrs?: Record<string, any>;
68
+ /**
69
+ * The producer(remote) info bound to this resource.
70
+ * Only present when the loader is invoked in a remote-related context
71
+ * (e.g. preloadRemote / loading remoteEntry).
72
+ */
73
+ remoteInfo?: RemoteInfo;
68
74
  }], CreateScriptHookReturn>;
69
75
  createLink: SyncHook<[{
70
76
  url: string;
71
77
  attrs?: Record<string, any>;
78
+ /**
79
+ * The producer(remote) info bound to this resource.
80
+ * Only present when the loader is invoked in a remote-related context
81
+ * (e.g. preloadRemote / loading remoteEntry).
82
+ */
83
+ remoteInfo?: RemoteInfo;
72
84
  }], void | HTMLLinkElement>;
73
- fetch: AsyncHook<[string, RequestInit], false | void | Promise<Response>>;
85
+ fetch: AsyncHook<[string, RequestInit, (RemoteInfo | undefined)?], false | void | Promise<Response>>;
74
86
  loadEntryError: AsyncHook<[{
75
87
  getRemoteEntry: typeof getRemoteEntry;
76
88
  origin: ModuleFederation;
package/dist/core.js CHANGED
@@ -30,7 +30,7 @@ var ModuleFederation = class {
30
30
  beforeInitContainer: new AsyncWaterfallHook("beforeInitContainer"),
31
31
  initContainer: new AsyncWaterfallHook("initContainer")
32
32
  });
33
- this.version = "2.3.2";
33
+ this.version = "2.4.0";
34
34
  this.moduleCache = /* @__PURE__ */ new Map();
35
35
  this.loaderHook = new PluginSystem({
36
36
  getModuleInfo: new SyncHook(),
@@ -121,7 +121,8 @@ var ModuleFederation = class {
121
121
  ...userOptions,
122
122
  plugins,
123
123
  remotes,
124
- shared: allShareInfos
124
+ shared: allShareInfos,
125
+ id: userOptionsRes.id || globalOptions.id
125
126
  };
126
127
  this.hooks.lifecycle.init.emit({
127
128
  origin: this,
package/dist/core.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"core.js","names":["Module"],"sources":["../src/core.ts"],"sourcesContent":["import { isBrowserEnvValue } from '@module-federation/sdk';\nimport type {\n CreateScriptHookReturn,\n GlobalModuleInfo,\n ModuleInfo,\n} from '@module-federation/sdk';\nimport {\n Options,\n PreloadRemoteArgs,\n RemoteEntryExports,\n Remote,\n Shared,\n ShareInfos,\n UserOptions,\n RemoteInfo,\n ShareScopeMap,\n InitScope,\n RemoteEntryInitOptions,\n CallFrom,\n} from './type';\nimport { getBuilderId, registerPlugins, getRemoteEntry, error } from './utils';\nimport {\n getShortErrorMsg,\n RUNTIME_010,\n runtimeDescMap,\n} from '@module-federation/error-codes';\nimport { Module } from './module';\nimport {\n AsyncHook,\n AsyncWaterfallHook,\n PluginSystem,\n SyncHook,\n SyncWaterfallHook,\n} from './utils/hooks';\nimport { generatePreloadAssetsPlugin } from './plugins/generate-preload-assets';\nimport { snapshotPlugin } from './plugins/snapshot';\nimport { getRemoteInfo } from './utils/load';\nimport { DEFAULT_SCOPE } from './constant';\nimport { SnapshotHandler } from './plugins/snapshot/SnapshotHandler';\nimport { SharedHandler } from './shared';\nimport { RemoteHandler } from './remote';\nimport { formatShareConfigs } from './utils/share';\n\n// Declare the global constant that will be defined by DefinePlugin\n// Default to true if not defined (e.g., when runtime-core is used outside of webpack)\n// so that snapshot functionality is included by default.\ndeclare const FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN: boolean;\nconst USE_SNAPSHOT =\n typeof FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN === 'boolean'\n ? !FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN\n : true; // Default to true (use snapshot) when not explicitly defined\n\nexport class ModuleFederation {\n options: Options;\n hooks = new PluginSystem({\n beforeInit: new SyncWaterfallHook<{\n userOptions: UserOptions;\n options: Options;\n origin: ModuleFederation;\n /**\n * @deprecated shareInfo will be removed soon, please use userOptions directly!\n */\n shareInfo: ShareInfos;\n }>('beforeInit'),\n init: new SyncHook<\n [\n {\n options: Options;\n origin: ModuleFederation;\n },\n ],\n void\n >(),\n // maybe will change, temporarily for internal use only\n beforeInitContainer: new AsyncWaterfallHook<{\n shareScope: ShareScopeMap[string];\n initScope: InitScope;\n remoteEntryInitOptions: RemoteEntryInitOptions;\n remoteInfo: RemoteInfo;\n origin: ModuleFederation;\n }>('beforeInitContainer'),\n // maybe will change, temporarily for internal use only\n initContainer: new AsyncWaterfallHook<{\n shareScope: ShareScopeMap[string];\n initScope: InitScope;\n remoteEntryInitOptions: RemoteEntryInitOptions;\n remoteInfo: RemoteInfo;\n remoteEntryExports: RemoteEntryExports;\n origin: ModuleFederation;\n id?: string;\n remoteSnapshot?: ModuleInfo;\n }>('initContainer'),\n });\n version: string = __VERSION__;\n name: string;\n moduleCache: Map<string, Module> = new Map();\n snapshotHandler: SnapshotHandler;\n sharedHandler: SharedHandler;\n remoteHandler: RemoteHandler;\n shareScopeMap: ShareScopeMap;\n loaderHook = new PluginSystem({\n // FIXME: may not be suitable , not open to the public yet\n getModuleInfo: new SyncHook<\n [\n {\n target: Record<string, any>;\n key: any;\n },\n ],\n { value: any | undefined; key: string } | void\n >(),\n createScript: new SyncHook<\n [\n {\n url: string;\n attrs?: Record<string, any>;\n },\n ],\n CreateScriptHookReturn\n >(),\n createLink: new SyncHook<\n [\n {\n url: string;\n attrs?: Record<string, any>;\n },\n ],\n HTMLLinkElement | void\n >(),\n fetch: new AsyncHook<\n [string, RequestInit],\n Promise<Response> | void | false\n >(),\n loadEntryError: new AsyncHook<\n [\n {\n getRemoteEntry: typeof getRemoteEntry;\n origin: ModuleFederation;\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports | undefined;\n globalLoading: Record<\n string,\n Promise<void | RemoteEntryExports> | undefined\n >;\n uniqueKey: string;\n },\n ],\n Promise<Promise<RemoteEntryExports | undefined> | undefined>\n >(),\n getModuleFactory: new AsyncHook<\n [\n {\n remoteEntryExports: RemoteEntryExports;\n expose: string;\n moduleInfo: RemoteInfo;\n },\n ],\n Promise<(() => Promise<Module>) | undefined>\n >(),\n });\n bridgeHook = new PluginSystem({\n beforeBridgeRender: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n afterBridgeRender: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n beforeBridgeDestroy: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n afterBridgeDestroy: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n });\n moduleInfo?: GlobalModuleInfo[string];\n\n constructor(userOptions: UserOptions) {\n const plugins = USE_SNAPSHOT\n ? [snapshotPlugin(), generatePreloadAssetsPlugin()]\n : [];\n // TODO: Validate the details of the options\n // Initialize options with default values\n const defaultOptions: Options = {\n id: getBuilderId(),\n name: userOptions.name,\n plugins,\n remotes: [],\n shared: {},\n inBrowser: isBrowserEnvValue,\n };\n\n this.name = userOptions.name;\n this.options = defaultOptions;\n this.snapshotHandler = new SnapshotHandler(this);\n this.sharedHandler = new SharedHandler(this);\n this.remoteHandler = new RemoteHandler(this);\n this.shareScopeMap = this.sharedHandler.shareScopeMap;\n this.registerPlugins([\n ...defaultOptions.plugins,\n ...(userOptions.plugins || []),\n ]);\n this.options = this.formatOptions(defaultOptions, userOptions);\n }\n\n initOptions(userOptions: UserOptions): Options {\n if (userOptions.name && userOptions.name !== this.options.name) {\n error(getShortErrorMsg(RUNTIME_010, runtimeDescMap));\n }\n this.registerPlugins(userOptions.plugins);\n const options = this.formatOptions(this.options, userOptions);\n\n this.options = options;\n\n return options;\n }\n\n async loadShare<T>(\n pkgName: string,\n extraOptions?: {\n customShareInfo?: Partial<Shared>;\n resolver?: (sharedOptions: ShareInfos[string]) => Shared;\n },\n ): Promise<false | (() => T | undefined)> {\n return this.sharedHandler.loadShare(pkgName, extraOptions);\n }\n\n // The lib function will only be available if the shared set by eager or runtime init is set or the shared is successfully loaded.\n // 1. If the loaded shared already exists globally, then it will be reused\n // 2. If lib exists in local shared, it will be used directly\n // 3. If the local get returns something other than Promise, then it will be used directly\n loadShareSync<T>(\n pkgName: string,\n extraOptions?: {\n customShareInfo?: Partial<Shared>;\n from?: 'build' | 'runtime';\n resolver?: (sharedOptions: ShareInfos[string]) => Shared;\n },\n ): () => T | never {\n return this.sharedHandler.loadShareSync(pkgName, extraOptions);\n }\n\n initializeSharing(\n shareScopeName = DEFAULT_SCOPE,\n extraOptions?: {\n initScope?: InitScope;\n from?: CallFrom;\n strategy?: Shared['strategy'];\n },\n ): Array<Promise<void>> {\n return this.sharedHandler.initializeSharing(shareScopeName, extraOptions);\n }\n\n initRawContainer(\n name: string,\n url: string,\n container: RemoteEntryExports,\n ): Module {\n const remoteInfo = getRemoteInfo({ name, entry: url });\n const module = new Module({ host: this, remoteInfo });\n\n module.remoteEntryExports = container;\n this.moduleCache.set(name, module);\n\n return module;\n }\n\n // eslint-disable-next-line max-lines-per-function\n // eslint-disable-next-line @typescript-eslint/member-ordering\n async loadRemote<T>(\n id: string,\n options?: { loadFactory?: boolean; from: CallFrom },\n ): Promise<T | null> {\n return this.remoteHandler.loadRemote(id, options);\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n async preloadRemote(preloadOptions: Array<PreloadRemoteArgs>): Promise<void> {\n return this.remoteHandler.preloadRemote(preloadOptions);\n }\n\n initShareScopeMap(\n scopeName: string,\n shareScope: ShareScopeMap[string],\n extraOptions: { hostShareScopeMap?: ShareScopeMap } = {},\n ): void {\n this.sharedHandler.initShareScopeMap(scopeName, shareScope, extraOptions);\n }\n\n formatOptions(globalOptions: Options, userOptions: UserOptions): Options {\n const { allShareInfos: shared } = formatShareConfigs(\n globalOptions,\n userOptions,\n );\n const { userOptions: userOptionsRes, options: globalOptionsRes } =\n this.hooks.lifecycle.beforeInit.emit({\n origin: this,\n userOptions,\n options: globalOptions,\n shareInfo: shared,\n });\n\n const remotes = this.remoteHandler.formatAndRegisterRemote(\n globalOptionsRes,\n userOptionsRes,\n );\n\n const { allShareInfos } = this.sharedHandler.registerShared(\n globalOptionsRes,\n userOptionsRes,\n );\n\n const plugins = [...globalOptionsRes.plugins];\n\n if (userOptionsRes.plugins) {\n userOptionsRes.plugins.forEach((plugin) => {\n if (!plugins.includes(plugin)) {\n plugins.push(plugin);\n }\n });\n }\n\n const optionsRes: Options = {\n ...globalOptions,\n ...userOptions,\n plugins,\n remotes,\n shared: allShareInfos,\n };\n\n this.hooks.lifecycle.init.emit({\n origin: this,\n options: optionsRes,\n });\n return optionsRes;\n }\n\n registerPlugins(plugins: UserOptions['plugins']) {\n const pluginRes = registerPlugins(plugins, this);\n // Merge plugin\n this.options.plugins = this.options.plugins.reduce((res, plugin) => {\n if (!plugin) return res;\n if (res && !res.find((item) => item.name === plugin.name)) {\n res.push(plugin);\n }\n return res;\n }, pluginRes || []);\n }\n registerRemotes(remotes: Remote[], options?: { force?: boolean }): void {\n return this.remoteHandler.registerRemotes(remotes, options);\n }\n\n registerShared(shared: UserOptions['shared']) {\n this.sharedHandler.registerShared(this.options, {\n ...this.options,\n shared,\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"core.js","names":["Module"],"sources":["../src/core.ts"],"sourcesContent":["import { isBrowserEnvValue } from '@module-federation/sdk';\nimport type {\n CreateScriptHookReturn,\n GlobalModuleInfo,\n ModuleInfo,\n} from '@module-federation/sdk';\nimport {\n Options,\n PreloadRemoteArgs,\n RemoteEntryExports,\n Remote,\n Shared,\n ShareInfos,\n UserOptions,\n RemoteInfo,\n ShareScopeMap,\n InitScope,\n RemoteEntryInitOptions,\n CallFrom,\n} from './type';\nimport { getBuilderId, registerPlugins, getRemoteEntry, error } from './utils';\nimport {\n getShortErrorMsg,\n RUNTIME_010,\n runtimeDescMap,\n} from '@module-federation/error-codes';\nimport { Module } from './module';\nimport {\n AsyncHook,\n AsyncWaterfallHook,\n PluginSystem,\n SyncHook,\n SyncWaterfallHook,\n} from './utils/hooks';\nimport { generatePreloadAssetsPlugin } from './plugins/generate-preload-assets';\nimport { snapshotPlugin } from './plugins/snapshot';\nimport { getRemoteInfo } from './utils/load';\nimport { DEFAULT_SCOPE } from './constant';\nimport { SnapshotHandler } from './plugins/snapshot/SnapshotHandler';\nimport { SharedHandler } from './shared';\nimport { RemoteHandler } from './remote';\nimport { formatShareConfigs } from './utils/share';\n\n// Declare the global constant that will be defined by DefinePlugin\n// Default to true if not defined (e.g., when runtime-core is used outside of webpack)\n// so that snapshot functionality is included by default.\ndeclare const FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN: boolean;\nconst USE_SNAPSHOT =\n typeof FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN === 'boolean'\n ? !FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN\n : true; // Default to true (use snapshot) when not explicitly defined\n\nexport class ModuleFederation {\n options: Options;\n hooks = new PluginSystem({\n beforeInit: new SyncWaterfallHook<{\n userOptions: UserOptions;\n options: Options;\n origin: ModuleFederation;\n /**\n * @deprecated shareInfo will be removed soon, please use userOptions directly!\n */\n shareInfo: ShareInfos;\n }>('beforeInit'),\n init: new SyncHook<\n [\n {\n options: Options;\n origin: ModuleFederation;\n },\n ],\n void\n >(),\n // maybe will change, temporarily for internal use only\n beforeInitContainer: new AsyncWaterfallHook<{\n shareScope: ShareScopeMap[string];\n initScope: InitScope;\n remoteEntryInitOptions: RemoteEntryInitOptions;\n remoteInfo: RemoteInfo;\n origin: ModuleFederation;\n }>('beforeInitContainer'),\n // maybe will change, temporarily for internal use only\n initContainer: new AsyncWaterfallHook<{\n shareScope: ShareScopeMap[string];\n initScope: InitScope;\n remoteEntryInitOptions: RemoteEntryInitOptions;\n remoteInfo: RemoteInfo;\n remoteEntryExports: RemoteEntryExports;\n origin: ModuleFederation;\n id?: string;\n remoteSnapshot?: ModuleInfo;\n }>('initContainer'),\n });\n version: string = __VERSION__;\n name: string;\n moduleCache: Map<string, Module> = new Map();\n snapshotHandler: SnapshotHandler;\n sharedHandler: SharedHandler;\n remoteHandler: RemoteHandler;\n shareScopeMap: ShareScopeMap;\n loaderHook = new PluginSystem({\n // FIXME: may not be suitable , not open to the public yet\n getModuleInfo: new SyncHook<\n [\n {\n target: Record<string, any>;\n key: any;\n },\n ],\n { value: any | undefined; key: string } | void\n >(),\n createScript: new SyncHook<\n [\n {\n url: string;\n attrs?: Record<string, any>;\n /**\n * The producer(remote) info bound to this resource.\n * Only present when the loader is invoked in a remote-related context\n * (e.g. preloadRemote / loading remoteEntry).\n */\n remoteInfo?: RemoteInfo;\n },\n ],\n CreateScriptHookReturn\n >(),\n createLink: new SyncHook<\n [\n {\n url: string;\n attrs?: Record<string, any>;\n /**\n * The producer(remote) info bound to this resource.\n * Only present when the loader is invoked in a remote-related context\n * (e.g. preloadRemote / loading remoteEntry).\n */\n remoteInfo?: RemoteInfo;\n },\n ],\n HTMLLinkElement | void\n >(),\n fetch: new AsyncHook<\n [string, RequestInit, RemoteInfo?],\n Promise<Response> | void | false\n >(),\n loadEntryError: new AsyncHook<\n [\n {\n getRemoteEntry: typeof getRemoteEntry;\n origin: ModuleFederation;\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports | undefined;\n globalLoading: Record<\n string,\n Promise<void | RemoteEntryExports> | undefined\n >;\n uniqueKey: string;\n },\n ],\n Promise<Promise<RemoteEntryExports | undefined> | undefined>\n >(),\n getModuleFactory: new AsyncHook<\n [\n {\n remoteEntryExports: RemoteEntryExports;\n expose: string;\n moduleInfo: RemoteInfo;\n },\n ],\n Promise<(() => Promise<Module>) | undefined>\n >(),\n });\n bridgeHook = new PluginSystem({\n beforeBridgeRender: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n afterBridgeRender: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n beforeBridgeDestroy: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n afterBridgeDestroy: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n });\n moduleInfo?: GlobalModuleInfo[string];\n\n constructor(userOptions: UserOptions) {\n const plugins = USE_SNAPSHOT\n ? [snapshotPlugin(), generatePreloadAssetsPlugin()]\n : [];\n // TODO: Validate the details of the options\n // Initialize options with default values\n const defaultOptions: Options = {\n id: getBuilderId(),\n name: userOptions.name,\n plugins,\n remotes: [],\n shared: {},\n inBrowser: isBrowserEnvValue,\n };\n\n this.name = userOptions.name;\n this.options = defaultOptions;\n this.snapshotHandler = new SnapshotHandler(this);\n this.sharedHandler = new SharedHandler(this);\n this.remoteHandler = new RemoteHandler(this);\n this.shareScopeMap = this.sharedHandler.shareScopeMap;\n this.registerPlugins([\n ...defaultOptions.plugins,\n ...(userOptions.plugins || []),\n ]);\n this.options = this.formatOptions(defaultOptions, userOptions);\n }\n\n initOptions(userOptions: UserOptions): Options {\n if (userOptions.name && userOptions.name !== this.options.name) {\n error(getShortErrorMsg(RUNTIME_010, runtimeDescMap));\n }\n this.registerPlugins(userOptions.plugins);\n const options = this.formatOptions(this.options, userOptions);\n\n this.options = options;\n\n return options;\n }\n\n async loadShare<T>(\n pkgName: string,\n extraOptions?: {\n customShareInfo?: Partial<Shared>;\n resolver?: (sharedOptions: ShareInfos[string]) => Shared;\n },\n ): Promise<false | (() => T | undefined)> {\n return this.sharedHandler.loadShare(pkgName, extraOptions);\n }\n\n // The lib function will only be available if the shared set by eager or runtime init is set or the shared is successfully loaded.\n // 1. If the loaded shared already exists globally, then it will be reused\n // 2. If lib exists in local shared, it will be used directly\n // 3. If the local get returns something other than Promise, then it will be used directly\n loadShareSync<T>(\n pkgName: string,\n extraOptions?: {\n customShareInfo?: Partial<Shared>;\n from?: 'build' | 'runtime';\n resolver?: (sharedOptions: ShareInfos[string]) => Shared;\n },\n ): () => T | never {\n return this.sharedHandler.loadShareSync(pkgName, extraOptions);\n }\n\n initializeSharing(\n shareScopeName = DEFAULT_SCOPE,\n extraOptions?: {\n initScope?: InitScope;\n from?: CallFrom;\n strategy?: Shared['strategy'];\n },\n ): Array<Promise<void>> {\n return this.sharedHandler.initializeSharing(shareScopeName, extraOptions);\n }\n\n initRawContainer(\n name: string,\n url: string,\n container: RemoteEntryExports,\n ): Module {\n const remoteInfo = getRemoteInfo({ name, entry: url });\n const module = new Module({ host: this, remoteInfo });\n\n module.remoteEntryExports = container;\n this.moduleCache.set(name, module);\n\n return module;\n }\n\n // eslint-disable-next-line max-lines-per-function\n // eslint-disable-next-line @typescript-eslint/member-ordering\n async loadRemote<T>(\n id: string,\n options?: { loadFactory?: boolean; from: CallFrom },\n ): Promise<T | null> {\n return this.remoteHandler.loadRemote(id, options);\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n async preloadRemote(preloadOptions: Array<PreloadRemoteArgs>): Promise<void> {\n return this.remoteHandler.preloadRemote(preloadOptions);\n }\n\n initShareScopeMap(\n scopeName: string,\n shareScope: ShareScopeMap[string],\n extraOptions: { hostShareScopeMap?: ShareScopeMap } = {},\n ): void {\n this.sharedHandler.initShareScopeMap(scopeName, shareScope, extraOptions);\n }\n\n formatOptions(globalOptions: Options, userOptions: UserOptions): Options {\n const { allShareInfos: shared } = formatShareConfigs(\n globalOptions,\n userOptions,\n );\n const { userOptions: userOptionsRes, options: globalOptionsRes } =\n this.hooks.lifecycle.beforeInit.emit({\n origin: this,\n userOptions,\n options: globalOptions,\n shareInfo: shared,\n });\n\n const remotes = this.remoteHandler.formatAndRegisterRemote(\n globalOptionsRes,\n userOptionsRes,\n );\n\n const { allShareInfos } = this.sharedHandler.registerShared(\n globalOptionsRes,\n userOptionsRes,\n );\n\n const plugins = [...globalOptionsRes.plugins];\n\n if (userOptionsRes.plugins) {\n userOptionsRes.plugins.forEach((plugin) => {\n if (!plugins.includes(plugin)) {\n plugins.push(plugin);\n }\n });\n }\n\n const optionsRes: Options = {\n ...globalOptions,\n ...userOptions,\n plugins,\n remotes,\n shared: allShareInfos,\n id: userOptionsRes.id || globalOptions.id,\n };\n\n this.hooks.lifecycle.init.emit({\n origin: this,\n options: optionsRes,\n });\n return optionsRes;\n }\n\n registerPlugins(plugins: UserOptions['plugins']) {\n const pluginRes = registerPlugins(plugins, this);\n // Merge plugin\n this.options.plugins = this.options.plugins.reduce((res, plugin) => {\n if (!plugin) return res;\n if (res && !res.find((item) => item.name === plugin.name)) {\n res.push(plugin);\n }\n return res;\n }, pluginRes || []);\n }\n registerRemotes(remotes: Remote[], options?: { force?: boolean }): void {\n return this.remoteHandler.registerRemotes(remotes, options);\n }\n\n registerShared(shared: UserOptions['shared']) {\n this.sharedHandler.registerShared(this.options, {\n ...this.options,\n shared,\n });\n }\n}\n"],"mappings":"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"}
package/dist/global.cjs CHANGED
@@ -65,7 +65,7 @@ function getGlobalFederationConstructor() {
65
65
  function setGlobalFederationConstructor(FederationConstructor, isDebug = (0, _module_federation_sdk.isDebugMode)()) {
66
66
  if (isDebug) {
67
67
  CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR__ = FederationConstructor;
68
- CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR_VERSION__ = "2.3.2";
68
+ CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR_VERSION__ = "2.4.0";
69
69
  }
70
70
  }
71
71
  function getInfoWithoutType(target, key) {
package/dist/global.js CHANGED
@@ -65,7 +65,7 @@ function getGlobalFederationConstructor() {
65
65
  function setGlobalFederationConstructor(FederationConstructor, isDebug = isDebugMode()) {
66
66
  if (isDebug) {
67
67
  CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR__ = FederationConstructor;
68
- CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR_VERSION__ = "2.3.2";
68
+ CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR_VERSION__ = "2.4.0";
69
69
  }
70
70
  }
71
71
  function getInfoWithoutType(target, key) {
@@ -1,6 +1,7 @@
1
1
  const require_logger = require('../../utils/logger.cjs');
2
2
  const require_tool = require('../../utils/tool.cjs');
3
3
  const require_global = require('../../global.cjs');
4
+ const require_load = require('../../utils/load.cjs');
4
5
  const require_context = require('../../utils/context.cjs');
5
6
  require('../../utils/index.cjs');
6
7
  const require_asyncHook = require('../../utils/hooks/asyncHook.cjs');
@@ -138,7 +139,7 @@ var SnapshotHandler = class {
138
139
  let manifestJson = this.manifestCache.get(manifestUrl);
139
140
  if (manifestJson) return manifestJson;
140
141
  try {
141
- let res = await this.loaderHook.lifecycle.fetch.emit(manifestUrl, {});
142
+ let res = await this.loaderHook.lifecycle.fetch.emit(manifestUrl, {}, require_load.getRemoteInfo(moduleInfo));
142
143
  if (!res || !(res instanceof Response)) res = await fetch(manifestUrl, {});
143
144
  manifestJson = await res.json();
144
145
  } catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"SnapshotHandler.cjs","names":["getGlobalSnapshotInfoByModuleInfo","getInfoWithoutType","getGlobalSnapshot","PluginSystem","AsyncHook","AsyncWaterfallHook","Global","isBrowserEnvValue","setGlobalSnapshotInfoByModuleInfo","isRemoteInfoWithEntry","RUNTIME_007","runtimeDescMap","optionsToMFContext","RUNTIME_003"],"sources":["../../../src/plugins/snapshot/SnapshotHandler.ts"],"sourcesContent":["import {\n GlobalModuleInfo,\n Manifest,\n ModuleInfo,\n generateSnapshotFromManifest,\n isManifestProvider,\n isBrowserEnvValue,\n} from '@module-federation/sdk';\nimport {\n RUNTIME_003,\n RUNTIME_007,\n runtimeDescMap,\n} from '@module-federation/error-codes';\nimport { Options, Remote } from '../../type';\nimport { isRemoteInfoWithEntry, error, optionsToMFContext } from '../../utils';\nimport {\n getGlobalSnapshot,\n setGlobalSnapshotInfoByModuleInfo,\n Global,\n addGlobalSnapshot,\n getGlobalSnapshotInfoByModuleInfo,\n getInfoWithoutType,\n} from '../../global';\nimport { PluginSystem, AsyncHook, AsyncWaterfallHook } from '../../utils/hooks';\nimport { ModuleFederation } from '../../core';\nimport { assert } from '../../utils/logger';\n\nexport function getGlobalRemoteInfo(\n moduleInfo: Remote,\n origin: ModuleFederation,\n): {\n hostGlobalSnapshot: ModuleInfo | undefined;\n globalSnapshot: ReturnType<typeof getGlobalSnapshot>;\n remoteSnapshot: GlobalModuleInfo[string] | undefined;\n} {\n const hostGlobalSnapshot = getGlobalSnapshotInfoByModuleInfo({\n name: origin.name,\n version: origin.options.version,\n });\n\n // get remote detail info from global\n const globalRemoteInfo =\n hostGlobalSnapshot &&\n 'remotesInfo' in hostGlobalSnapshot &&\n hostGlobalSnapshot.remotesInfo &&\n getInfoWithoutType(hostGlobalSnapshot.remotesInfo, moduleInfo.name).value;\n\n if (globalRemoteInfo && globalRemoteInfo.matchedVersion) {\n return {\n hostGlobalSnapshot,\n globalSnapshot: getGlobalSnapshot(),\n remoteSnapshot: getGlobalSnapshotInfoByModuleInfo({\n name: moduleInfo.name,\n version: globalRemoteInfo.matchedVersion,\n }),\n };\n }\n\n return {\n hostGlobalSnapshot: undefined,\n globalSnapshot: getGlobalSnapshot(),\n remoteSnapshot: getGlobalSnapshotInfoByModuleInfo({\n name: moduleInfo.name,\n version: 'version' in moduleInfo ? moduleInfo.version : undefined,\n }),\n };\n}\n\nexport class SnapshotHandler {\n loadingHostSnapshot: Promise<GlobalModuleInfo | void> | null = null;\n HostInstance: ModuleFederation;\n manifestCache: Map<string, Manifest> = new Map();\n hooks = new PluginSystem({\n beforeLoadRemoteSnapshot: new AsyncHook<\n [\n {\n options: Options;\n moduleInfo: Remote;\n },\n ],\n void\n >('beforeLoadRemoteSnapshot'),\n loadSnapshot: new AsyncWaterfallHook<{\n options: Options;\n moduleInfo: Remote;\n hostGlobalSnapshot: GlobalModuleInfo[string] | undefined;\n globalSnapshot: ReturnType<typeof getGlobalSnapshot>;\n remoteSnapshot?: GlobalModuleInfo[string] | undefined;\n }>('loadGlobalSnapshot'),\n loadRemoteSnapshot: new AsyncWaterfallHook<{\n options: Options;\n moduleInfo: Remote;\n manifestJson?: Manifest;\n manifestUrl?: string;\n remoteSnapshot: ModuleInfo;\n from: 'global' | 'manifest';\n }>('loadRemoteSnapshot'),\n afterLoadSnapshot: new AsyncWaterfallHook<{\n id?: string;\n host: ModuleFederation;\n options: Options;\n moduleInfo: Remote;\n remoteSnapshot: ModuleInfo;\n }>('afterLoadSnapshot'),\n });\n loaderHook: ModuleFederation['loaderHook'];\n manifestLoading: Record<string, Promise<ModuleInfo>> =\n Global.__FEDERATION__.__MANIFEST_LOADING__;\n\n constructor(HostInstance: ModuleFederation) {\n this.HostInstance = HostInstance;\n this.loaderHook = HostInstance.loaderHook;\n }\n\n // eslint-disable-next-line max-lines-per-function\n async loadRemoteSnapshotInfo({\n moduleInfo,\n id,\n expose,\n }: {\n moduleInfo: Remote;\n id?: string;\n expose?: string;\n }):\n | Promise<{\n remoteSnapshot: ModuleInfo;\n globalSnapshot: GlobalModuleInfo;\n }>\n | never {\n const { options } = this.HostInstance;\n\n await this.hooks.lifecycle.beforeLoadRemoteSnapshot.emit({\n options,\n moduleInfo,\n });\n\n let hostSnapshot = getGlobalSnapshotInfoByModuleInfo({\n name: this.HostInstance.options.name,\n version: this.HostInstance.options.version,\n });\n\n if (!hostSnapshot) {\n hostSnapshot = {\n version: this.HostInstance.options.version || '',\n remoteEntry: '',\n remotesInfo: {},\n };\n addGlobalSnapshot({\n [this.HostInstance.options.name]: hostSnapshot,\n });\n }\n\n // 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.\n // 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.\n if (\n hostSnapshot &&\n 'remotesInfo' in hostSnapshot &&\n !getInfoWithoutType(hostSnapshot.remotesInfo, moduleInfo.name).value\n ) {\n if ('version' in moduleInfo || 'entry' in moduleInfo) {\n hostSnapshot.remotesInfo = {\n ...hostSnapshot?.remotesInfo,\n [moduleInfo.name]: {\n matchedVersion:\n 'version' in moduleInfo ? moduleInfo.version : moduleInfo.entry,\n },\n };\n }\n }\n\n const { hostGlobalSnapshot, remoteSnapshot, globalSnapshot } =\n this.getGlobalRemoteInfo(moduleInfo);\n const {\n remoteSnapshot: globalRemoteSnapshot,\n globalSnapshot: globalSnapshotRes,\n } = await this.hooks.lifecycle.loadSnapshot.emit({\n options,\n moduleInfo,\n hostGlobalSnapshot,\n remoteSnapshot,\n globalSnapshot,\n });\n\n let mSnapshot;\n let gSnapshot;\n // global snapshot includes manifest or module info includes manifest\n if (globalRemoteSnapshot) {\n if (isManifestProvider(globalRemoteSnapshot)) {\n const remoteEntry = isBrowserEnvValue\n ? globalRemoteSnapshot.remoteEntry\n : globalRemoteSnapshot.ssrRemoteEntry ||\n globalRemoteSnapshot.remoteEntry ||\n '';\n const moduleSnapshot = await this.getManifestJson(\n remoteEntry,\n moduleInfo,\n {},\n );\n // eslint-disable-next-line @typescript-eslint/no-shadow\n const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(\n {\n ...moduleInfo,\n // The global remote may be overridden\n // Therefore, set the snapshot key to the global address of the actual request\n entry: remoteEntry,\n },\n moduleSnapshot,\n );\n mSnapshot = moduleSnapshot;\n gSnapshot = globalSnapshotRes;\n } else {\n const { remoteSnapshot: remoteSnapshotRes } =\n await this.hooks.lifecycle.loadRemoteSnapshot.emit({\n options: this.HostInstance.options,\n moduleInfo,\n remoteSnapshot: globalRemoteSnapshot,\n from: 'global',\n });\n mSnapshot = remoteSnapshotRes;\n gSnapshot = globalSnapshotRes;\n }\n } else {\n if (isRemoteInfoWithEntry(moduleInfo)) {\n // get from manifest.json and merge remote info from remote server\n const moduleSnapshot = await this.getManifestJson(\n moduleInfo.entry,\n moduleInfo,\n {},\n );\n // eslint-disable-next-line @typescript-eslint/no-shadow\n const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(\n moduleInfo,\n moduleSnapshot,\n );\n const { remoteSnapshot: remoteSnapshotRes } =\n await this.hooks.lifecycle.loadRemoteSnapshot.emit({\n options: this.HostInstance.options,\n moduleInfo,\n remoteSnapshot: moduleSnapshot,\n from: 'global',\n });\n\n mSnapshot = remoteSnapshotRes;\n gSnapshot = globalSnapshotRes;\n } else {\n error(\n RUNTIME_007,\n runtimeDescMap,\n {\n remoteName: moduleInfo.name,\n remoteVersion: moduleInfo.version,\n hostName: this.HostInstance.options.name,\n globalSnapshot: JSON.stringify(globalSnapshotRes),\n },\n undefined,\n optionsToMFContext(this.HostInstance.options),\n );\n }\n }\n\n await this.hooks.lifecycle.afterLoadSnapshot.emit({\n id,\n host: this.HostInstance,\n options,\n moduleInfo,\n remoteSnapshot: mSnapshot,\n });\n\n return {\n remoteSnapshot: mSnapshot,\n globalSnapshot: gSnapshot,\n };\n }\n\n getGlobalRemoteInfo(moduleInfo: Remote): {\n hostGlobalSnapshot: ModuleInfo | undefined;\n globalSnapshot: ReturnType<typeof getGlobalSnapshot>;\n remoteSnapshot: GlobalModuleInfo[string] | undefined;\n } {\n return getGlobalRemoteInfo(moduleInfo, this.HostInstance);\n }\n\n private async getManifestJson(\n manifestUrl: string,\n moduleInfo: Remote,\n extraOptions: Record<string, any>,\n ): Promise<ModuleInfo> {\n const getManifest = async (): Promise<Manifest> => {\n let manifestJson: Manifest | undefined =\n this.manifestCache.get(manifestUrl);\n if (manifestJson) {\n return manifestJson;\n }\n try {\n let res = await this.loaderHook.lifecycle.fetch.emit(manifestUrl, {});\n if (!res || !(res instanceof Response)) {\n res = await fetch(manifestUrl, {});\n }\n manifestJson = (await res.json()) as Manifest;\n } catch (err) {\n manifestJson =\n (await this.HostInstance.remoteHandler.hooks.lifecycle.errorLoadRemote.emit(\n {\n id: manifestUrl,\n error: err,\n from: 'runtime',\n lifecycle: 'afterResolve',\n origin: this.HostInstance,\n },\n )) as Manifest | undefined;\n\n if (!manifestJson) {\n delete this.manifestLoading[manifestUrl];\n error(\n RUNTIME_003,\n runtimeDescMap,\n {\n manifestUrl,\n moduleName: moduleInfo.name,\n hostName: this.HostInstance.options.name,\n },\n `${err}`,\n optionsToMFContext(this.HostInstance.options),\n );\n }\n }\n\n assert(\n manifestJson.metaData && manifestJson.exposes && manifestJson.shared,\n `\"${manifestUrl}\" is not a valid federation manifest for remote \"${moduleInfo.name}\". Missing required fields: ${[!manifestJson.metaData && 'metaData', !manifestJson.exposes && 'exposes', !manifestJson.shared && 'shared'].filter(Boolean).join(', ')}.`,\n );\n this.manifestCache.set(manifestUrl, manifestJson);\n return manifestJson;\n };\n\n const asyncLoadProcess = async () => {\n const manifestJson = await getManifest();\n const remoteSnapshot = generateSnapshotFromManifest(manifestJson, {\n version: manifestUrl,\n });\n\n const { remoteSnapshot: remoteSnapshotRes } =\n await this.hooks.lifecycle.loadRemoteSnapshot.emit({\n options: this.HostInstance.options,\n moduleInfo,\n manifestJson,\n remoteSnapshot,\n manifestUrl,\n from: 'manifest',\n });\n return remoteSnapshotRes;\n };\n\n if (!this.manifestLoading[manifestUrl]) {\n this.manifestLoading[manifestUrl] = asyncLoadProcess().then((res) => res);\n }\n return this.manifestLoading[manifestUrl];\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"SnapshotHandler.cjs","names":["getGlobalSnapshotInfoByModuleInfo","getInfoWithoutType","getGlobalSnapshot","PluginSystem","AsyncHook","AsyncWaterfallHook","Global","isBrowserEnvValue","setGlobalSnapshotInfoByModuleInfo","isRemoteInfoWithEntry","RUNTIME_007","runtimeDescMap","optionsToMFContext","getRemoteInfo","RUNTIME_003"],"sources":["../../../src/plugins/snapshot/SnapshotHandler.ts"],"sourcesContent":["import {\n GlobalModuleInfo,\n Manifest,\n ModuleInfo,\n generateSnapshotFromManifest,\n isManifestProvider,\n isBrowserEnvValue,\n} from '@module-federation/sdk';\nimport {\n RUNTIME_003,\n RUNTIME_007,\n runtimeDescMap,\n} from '@module-federation/error-codes';\nimport { Options, Remote } from '../../type';\nimport {\n isRemoteInfoWithEntry,\n error,\n optionsToMFContext,\n getRemoteInfo,\n} from '../../utils';\nimport {\n getGlobalSnapshot,\n setGlobalSnapshotInfoByModuleInfo,\n Global,\n addGlobalSnapshot,\n getGlobalSnapshotInfoByModuleInfo,\n getInfoWithoutType,\n} from '../../global';\nimport { PluginSystem, AsyncHook, AsyncWaterfallHook } from '../../utils/hooks';\nimport { ModuleFederation } from '../../core';\nimport { assert } from '../../utils/logger';\n\nexport function getGlobalRemoteInfo(\n moduleInfo: Remote,\n origin: ModuleFederation,\n): {\n hostGlobalSnapshot: ModuleInfo | undefined;\n globalSnapshot: ReturnType<typeof getGlobalSnapshot>;\n remoteSnapshot: GlobalModuleInfo[string] | undefined;\n} {\n const hostGlobalSnapshot = getGlobalSnapshotInfoByModuleInfo({\n name: origin.name,\n version: origin.options.version,\n });\n\n // get remote detail info from global\n const globalRemoteInfo =\n hostGlobalSnapshot &&\n 'remotesInfo' in hostGlobalSnapshot &&\n hostGlobalSnapshot.remotesInfo &&\n getInfoWithoutType(hostGlobalSnapshot.remotesInfo, moduleInfo.name).value;\n\n if (globalRemoteInfo && globalRemoteInfo.matchedVersion) {\n return {\n hostGlobalSnapshot,\n globalSnapshot: getGlobalSnapshot(),\n remoteSnapshot: getGlobalSnapshotInfoByModuleInfo({\n name: moduleInfo.name,\n version: globalRemoteInfo.matchedVersion,\n }),\n };\n }\n\n return {\n hostGlobalSnapshot: undefined,\n globalSnapshot: getGlobalSnapshot(),\n remoteSnapshot: getGlobalSnapshotInfoByModuleInfo({\n name: moduleInfo.name,\n version: 'version' in moduleInfo ? moduleInfo.version : undefined,\n }),\n };\n}\n\nexport class SnapshotHandler {\n loadingHostSnapshot: Promise<GlobalModuleInfo | void> | null = null;\n HostInstance: ModuleFederation;\n manifestCache: Map<string, Manifest> = new Map();\n hooks = new PluginSystem({\n beforeLoadRemoteSnapshot: new AsyncHook<\n [\n {\n options: Options;\n moduleInfo: Remote;\n },\n ],\n void\n >('beforeLoadRemoteSnapshot'),\n loadSnapshot: new AsyncWaterfallHook<{\n options: Options;\n moduleInfo: Remote;\n hostGlobalSnapshot: GlobalModuleInfo[string] | undefined;\n globalSnapshot: ReturnType<typeof getGlobalSnapshot>;\n remoteSnapshot?: GlobalModuleInfo[string] | undefined;\n }>('loadGlobalSnapshot'),\n loadRemoteSnapshot: new AsyncWaterfallHook<{\n options: Options;\n moduleInfo: Remote;\n manifestJson?: Manifest;\n manifestUrl?: string;\n remoteSnapshot: ModuleInfo;\n from: 'global' | 'manifest';\n }>('loadRemoteSnapshot'),\n afterLoadSnapshot: new AsyncWaterfallHook<{\n id?: string;\n host: ModuleFederation;\n options: Options;\n moduleInfo: Remote;\n remoteSnapshot: ModuleInfo;\n }>('afterLoadSnapshot'),\n });\n loaderHook: ModuleFederation['loaderHook'];\n manifestLoading: Record<string, Promise<ModuleInfo>> =\n Global.__FEDERATION__.__MANIFEST_LOADING__;\n\n constructor(HostInstance: ModuleFederation) {\n this.HostInstance = HostInstance;\n this.loaderHook = HostInstance.loaderHook;\n }\n\n // eslint-disable-next-line max-lines-per-function\n async loadRemoteSnapshotInfo({\n moduleInfo,\n id,\n expose,\n }: {\n moduleInfo: Remote;\n id?: string;\n expose?: string;\n }):\n | Promise<{\n remoteSnapshot: ModuleInfo;\n globalSnapshot: GlobalModuleInfo;\n }>\n | never {\n const { options } = this.HostInstance;\n\n await this.hooks.lifecycle.beforeLoadRemoteSnapshot.emit({\n options,\n moduleInfo,\n });\n\n let hostSnapshot = getGlobalSnapshotInfoByModuleInfo({\n name: this.HostInstance.options.name,\n version: this.HostInstance.options.version,\n });\n\n if (!hostSnapshot) {\n hostSnapshot = {\n version: this.HostInstance.options.version || '',\n remoteEntry: '',\n remotesInfo: {},\n };\n addGlobalSnapshot({\n [this.HostInstance.options.name]: hostSnapshot,\n });\n }\n\n // 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.\n // 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.\n if (\n hostSnapshot &&\n 'remotesInfo' in hostSnapshot &&\n !getInfoWithoutType(hostSnapshot.remotesInfo, moduleInfo.name).value\n ) {\n if ('version' in moduleInfo || 'entry' in moduleInfo) {\n hostSnapshot.remotesInfo = {\n ...hostSnapshot?.remotesInfo,\n [moduleInfo.name]: {\n matchedVersion:\n 'version' in moduleInfo ? moduleInfo.version : moduleInfo.entry,\n },\n };\n }\n }\n\n const { hostGlobalSnapshot, remoteSnapshot, globalSnapshot } =\n this.getGlobalRemoteInfo(moduleInfo);\n const {\n remoteSnapshot: globalRemoteSnapshot,\n globalSnapshot: globalSnapshotRes,\n } = await this.hooks.lifecycle.loadSnapshot.emit({\n options,\n moduleInfo,\n hostGlobalSnapshot,\n remoteSnapshot,\n globalSnapshot,\n });\n\n let mSnapshot;\n let gSnapshot;\n // global snapshot includes manifest or module info includes manifest\n if (globalRemoteSnapshot) {\n if (isManifestProvider(globalRemoteSnapshot)) {\n const remoteEntry = isBrowserEnvValue\n ? globalRemoteSnapshot.remoteEntry\n : globalRemoteSnapshot.ssrRemoteEntry ||\n globalRemoteSnapshot.remoteEntry ||\n '';\n const moduleSnapshot = await this.getManifestJson(\n remoteEntry,\n moduleInfo,\n {},\n );\n // eslint-disable-next-line @typescript-eslint/no-shadow\n const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(\n {\n ...moduleInfo,\n // The global remote may be overridden\n // Therefore, set the snapshot key to the global address of the actual request\n entry: remoteEntry,\n },\n moduleSnapshot,\n );\n mSnapshot = moduleSnapshot;\n gSnapshot = globalSnapshotRes;\n } else {\n const { remoteSnapshot: remoteSnapshotRes } =\n await this.hooks.lifecycle.loadRemoteSnapshot.emit({\n options: this.HostInstance.options,\n moduleInfo,\n remoteSnapshot: globalRemoteSnapshot,\n from: 'global',\n });\n mSnapshot = remoteSnapshotRes;\n gSnapshot = globalSnapshotRes;\n }\n } else {\n if (isRemoteInfoWithEntry(moduleInfo)) {\n // get from manifest.json and merge remote info from remote server\n const moduleSnapshot = await this.getManifestJson(\n moduleInfo.entry,\n moduleInfo,\n {},\n );\n // eslint-disable-next-line @typescript-eslint/no-shadow\n const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(\n moduleInfo,\n moduleSnapshot,\n );\n const { remoteSnapshot: remoteSnapshotRes } =\n await this.hooks.lifecycle.loadRemoteSnapshot.emit({\n options: this.HostInstance.options,\n moduleInfo,\n remoteSnapshot: moduleSnapshot,\n from: 'global',\n });\n\n mSnapshot = remoteSnapshotRes;\n gSnapshot = globalSnapshotRes;\n } else {\n error(\n RUNTIME_007,\n runtimeDescMap,\n {\n remoteName: moduleInfo.name,\n remoteVersion: moduleInfo.version,\n hostName: this.HostInstance.options.name,\n globalSnapshot: JSON.stringify(globalSnapshotRes),\n },\n undefined,\n optionsToMFContext(this.HostInstance.options),\n );\n }\n }\n\n await this.hooks.lifecycle.afterLoadSnapshot.emit({\n id,\n host: this.HostInstance,\n options,\n moduleInfo,\n remoteSnapshot: mSnapshot,\n });\n\n return {\n remoteSnapshot: mSnapshot,\n globalSnapshot: gSnapshot,\n };\n }\n\n getGlobalRemoteInfo(moduleInfo: Remote): {\n hostGlobalSnapshot: ModuleInfo | undefined;\n globalSnapshot: ReturnType<typeof getGlobalSnapshot>;\n remoteSnapshot: GlobalModuleInfo[string] | undefined;\n } {\n return getGlobalRemoteInfo(moduleInfo, this.HostInstance);\n }\n\n private async getManifestJson(\n manifestUrl: string,\n moduleInfo: Remote,\n extraOptions: Record<string, any>,\n ): Promise<ModuleInfo> {\n const getManifest = async (): Promise<Manifest> => {\n let manifestJson: Manifest | undefined =\n this.manifestCache.get(manifestUrl);\n if (manifestJson) {\n return manifestJson;\n }\n try {\n let res = await this.loaderHook.lifecycle.fetch.emit(\n manifestUrl,\n {},\n getRemoteInfo(moduleInfo),\n );\n if (!res || !(res instanceof Response)) {\n res = await fetch(manifestUrl, {});\n }\n manifestJson = (await res.json()) as Manifest;\n } catch (err) {\n manifestJson =\n (await this.HostInstance.remoteHandler.hooks.lifecycle.errorLoadRemote.emit(\n {\n id: manifestUrl,\n error: err,\n from: 'runtime',\n lifecycle: 'afterResolve',\n origin: this.HostInstance,\n },\n )) as Manifest | undefined;\n\n if (!manifestJson) {\n delete this.manifestLoading[manifestUrl];\n error(\n RUNTIME_003,\n runtimeDescMap,\n {\n manifestUrl,\n moduleName: moduleInfo.name,\n hostName: this.HostInstance.options.name,\n },\n `${err}`,\n optionsToMFContext(this.HostInstance.options),\n );\n }\n }\n\n assert(\n manifestJson.metaData && manifestJson.exposes && manifestJson.shared,\n `\"${manifestUrl}\" is not a valid federation manifest for remote \"${moduleInfo.name}\". Missing required fields: ${[!manifestJson.metaData && 'metaData', !manifestJson.exposes && 'exposes', !manifestJson.shared && 'shared'].filter(Boolean).join(', ')}.`,\n );\n this.manifestCache.set(manifestUrl, manifestJson);\n return manifestJson;\n };\n\n const asyncLoadProcess = async () => {\n const manifestJson = await getManifest();\n const remoteSnapshot = generateSnapshotFromManifest(manifestJson, {\n version: manifestUrl,\n });\n\n const { remoteSnapshot: remoteSnapshotRes } =\n await this.hooks.lifecycle.loadRemoteSnapshot.emit({\n options: this.HostInstance.options,\n moduleInfo,\n manifestJson,\n remoteSnapshot,\n manifestUrl,\n from: 'manifest',\n });\n return remoteSnapshotRes;\n };\n\n if (!this.manifestLoading[manifestUrl]) {\n this.manifestLoading[manifestUrl] = asyncLoadProcess().then((res) => res);\n }\n return this.manifestLoading[manifestUrl];\n }\n}\n"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { assert, error } from "../../utils/logger.js";
2
2
  import { isRemoteInfoWithEntry } from "../../utils/tool.js";
3
3
  import { Global, addGlobalSnapshot, getGlobalSnapshot, getGlobalSnapshotInfoByModuleInfo, getInfoWithoutType, setGlobalSnapshotInfoByModuleInfo } from "../../global.js";
4
+ import { getRemoteInfo } from "../../utils/load.js";
4
5
  import { optionsToMFContext } from "../../utils/context.js";
5
6
  import "../../utils/index.js";
6
7
  import { AsyncHook } from "../../utils/hooks/asyncHook.js";
@@ -138,7 +139,7 @@ var SnapshotHandler = class {
138
139
  let manifestJson = this.manifestCache.get(manifestUrl);
139
140
  if (manifestJson) return manifestJson;
140
141
  try {
141
- let res = await this.loaderHook.lifecycle.fetch.emit(manifestUrl, {});
142
+ let res = await this.loaderHook.lifecycle.fetch.emit(manifestUrl, {}, getRemoteInfo(moduleInfo));
142
143
  if (!res || !(res instanceof Response)) res = await fetch(manifestUrl, {});
143
144
  manifestJson = await res.json();
144
145
  } catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"SnapshotHandler.js","names":[],"sources":["../../../src/plugins/snapshot/SnapshotHandler.ts"],"sourcesContent":["import {\n GlobalModuleInfo,\n Manifest,\n ModuleInfo,\n generateSnapshotFromManifest,\n isManifestProvider,\n isBrowserEnvValue,\n} from '@module-federation/sdk';\nimport {\n RUNTIME_003,\n RUNTIME_007,\n runtimeDescMap,\n} from '@module-federation/error-codes';\nimport { Options, Remote } from '../../type';\nimport { isRemoteInfoWithEntry, error, optionsToMFContext } from '../../utils';\nimport {\n getGlobalSnapshot,\n setGlobalSnapshotInfoByModuleInfo,\n Global,\n addGlobalSnapshot,\n getGlobalSnapshotInfoByModuleInfo,\n getInfoWithoutType,\n} from '../../global';\nimport { PluginSystem, AsyncHook, AsyncWaterfallHook } from '../../utils/hooks';\nimport { ModuleFederation } from '../../core';\nimport { assert } from '../../utils/logger';\n\nexport function getGlobalRemoteInfo(\n moduleInfo: Remote,\n origin: ModuleFederation,\n): {\n hostGlobalSnapshot: ModuleInfo | undefined;\n globalSnapshot: ReturnType<typeof getGlobalSnapshot>;\n remoteSnapshot: GlobalModuleInfo[string] | undefined;\n} {\n const hostGlobalSnapshot = getGlobalSnapshotInfoByModuleInfo({\n name: origin.name,\n version: origin.options.version,\n });\n\n // get remote detail info from global\n const globalRemoteInfo =\n hostGlobalSnapshot &&\n 'remotesInfo' in hostGlobalSnapshot &&\n hostGlobalSnapshot.remotesInfo &&\n getInfoWithoutType(hostGlobalSnapshot.remotesInfo, moduleInfo.name).value;\n\n if (globalRemoteInfo && globalRemoteInfo.matchedVersion) {\n return {\n hostGlobalSnapshot,\n globalSnapshot: getGlobalSnapshot(),\n remoteSnapshot: getGlobalSnapshotInfoByModuleInfo({\n name: moduleInfo.name,\n version: globalRemoteInfo.matchedVersion,\n }),\n };\n }\n\n return {\n hostGlobalSnapshot: undefined,\n globalSnapshot: getGlobalSnapshot(),\n remoteSnapshot: getGlobalSnapshotInfoByModuleInfo({\n name: moduleInfo.name,\n version: 'version' in moduleInfo ? moduleInfo.version : undefined,\n }),\n };\n}\n\nexport class SnapshotHandler {\n loadingHostSnapshot: Promise<GlobalModuleInfo | void> | null = null;\n HostInstance: ModuleFederation;\n manifestCache: Map<string, Manifest> = new Map();\n hooks = new PluginSystem({\n beforeLoadRemoteSnapshot: new AsyncHook<\n [\n {\n options: Options;\n moduleInfo: Remote;\n },\n ],\n void\n >('beforeLoadRemoteSnapshot'),\n loadSnapshot: new AsyncWaterfallHook<{\n options: Options;\n moduleInfo: Remote;\n hostGlobalSnapshot: GlobalModuleInfo[string] | undefined;\n globalSnapshot: ReturnType<typeof getGlobalSnapshot>;\n remoteSnapshot?: GlobalModuleInfo[string] | undefined;\n }>('loadGlobalSnapshot'),\n loadRemoteSnapshot: new AsyncWaterfallHook<{\n options: Options;\n moduleInfo: Remote;\n manifestJson?: Manifest;\n manifestUrl?: string;\n remoteSnapshot: ModuleInfo;\n from: 'global' | 'manifest';\n }>('loadRemoteSnapshot'),\n afterLoadSnapshot: new AsyncWaterfallHook<{\n id?: string;\n host: ModuleFederation;\n options: Options;\n moduleInfo: Remote;\n remoteSnapshot: ModuleInfo;\n }>('afterLoadSnapshot'),\n });\n loaderHook: ModuleFederation['loaderHook'];\n manifestLoading: Record<string, Promise<ModuleInfo>> =\n Global.__FEDERATION__.__MANIFEST_LOADING__;\n\n constructor(HostInstance: ModuleFederation) {\n this.HostInstance = HostInstance;\n this.loaderHook = HostInstance.loaderHook;\n }\n\n // eslint-disable-next-line max-lines-per-function\n async loadRemoteSnapshotInfo({\n moduleInfo,\n id,\n expose,\n }: {\n moduleInfo: Remote;\n id?: string;\n expose?: string;\n }):\n | Promise<{\n remoteSnapshot: ModuleInfo;\n globalSnapshot: GlobalModuleInfo;\n }>\n | never {\n const { options } = this.HostInstance;\n\n await this.hooks.lifecycle.beforeLoadRemoteSnapshot.emit({\n options,\n moduleInfo,\n });\n\n let hostSnapshot = getGlobalSnapshotInfoByModuleInfo({\n name: this.HostInstance.options.name,\n version: this.HostInstance.options.version,\n });\n\n if (!hostSnapshot) {\n hostSnapshot = {\n version: this.HostInstance.options.version || '',\n remoteEntry: '',\n remotesInfo: {},\n };\n addGlobalSnapshot({\n [this.HostInstance.options.name]: hostSnapshot,\n });\n }\n\n // 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.\n // 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.\n if (\n hostSnapshot &&\n 'remotesInfo' in hostSnapshot &&\n !getInfoWithoutType(hostSnapshot.remotesInfo, moduleInfo.name).value\n ) {\n if ('version' in moduleInfo || 'entry' in moduleInfo) {\n hostSnapshot.remotesInfo = {\n ...hostSnapshot?.remotesInfo,\n [moduleInfo.name]: {\n matchedVersion:\n 'version' in moduleInfo ? moduleInfo.version : moduleInfo.entry,\n },\n };\n }\n }\n\n const { hostGlobalSnapshot, remoteSnapshot, globalSnapshot } =\n this.getGlobalRemoteInfo(moduleInfo);\n const {\n remoteSnapshot: globalRemoteSnapshot,\n globalSnapshot: globalSnapshotRes,\n } = await this.hooks.lifecycle.loadSnapshot.emit({\n options,\n moduleInfo,\n hostGlobalSnapshot,\n remoteSnapshot,\n globalSnapshot,\n });\n\n let mSnapshot;\n let gSnapshot;\n // global snapshot includes manifest or module info includes manifest\n if (globalRemoteSnapshot) {\n if (isManifestProvider(globalRemoteSnapshot)) {\n const remoteEntry = isBrowserEnvValue\n ? globalRemoteSnapshot.remoteEntry\n : globalRemoteSnapshot.ssrRemoteEntry ||\n globalRemoteSnapshot.remoteEntry ||\n '';\n const moduleSnapshot = await this.getManifestJson(\n remoteEntry,\n moduleInfo,\n {},\n );\n // eslint-disable-next-line @typescript-eslint/no-shadow\n const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(\n {\n ...moduleInfo,\n // The global remote may be overridden\n // Therefore, set the snapshot key to the global address of the actual request\n entry: remoteEntry,\n },\n moduleSnapshot,\n );\n mSnapshot = moduleSnapshot;\n gSnapshot = globalSnapshotRes;\n } else {\n const { remoteSnapshot: remoteSnapshotRes } =\n await this.hooks.lifecycle.loadRemoteSnapshot.emit({\n options: this.HostInstance.options,\n moduleInfo,\n remoteSnapshot: globalRemoteSnapshot,\n from: 'global',\n });\n mSnapshot = remoteSnapshotRes;\n gSnapshot = globalSnapshotRes;\n }\n } else {\n if (isRemoteInfoWithEntry(moduleInfo)) {\n // get from manifest.json and merge remote info from remote server\n const moduleSnapshot = await this.getManifestJson(\n moduleInfo.entry,\n moduleInfo,\n {},\n );\n // eslint-disable-next-line @typescript-eslint/no-shadow\n const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(\n moduleInfo,\n moduleSnapshot,\n );\n const { remoteSnapshot: remoteSnapshotRes } =\n await this.hooks.lifecycle.loadRemoteSnapshot.emit({\n options: this.HostInstance.options,\n moduleInfo,\n remoteSnapshot: moduleSnapshot,\n from: 'global',\n });\n\n mSnapshot = remoteSnapshotRes;\n gSnapshot = globalSnapshotRes;\n } else {\n error(\n RUNTIME_007,\n runtimeDescMap,\n {\n remoteName: moduleInfo.name,\n remoteVersion: moduleInfo.version,\n hostName: this.HostInstance.options.name,\n globalSnapshot: JSON.stringify(globalSnapshotRes),\n },\n undefined,\n optionsToMFContext(this.HostInstance.options),\n );\n }\n }\n\n await this.hooks.lifecycle.afterLoadSnapshot.emit({\n id,\n host: this.HostInstance,\n options,\n moduleInfo,\n remoteSnapshot: mSnapshot,\n });\n\n return {\n remoteSnapshot: mSnapshot,\n globalSnapshot: gSnapshot,\n };\n }\n\n getGlobalRemoteInfo(moduleInfo: Remote): {\n hostGlobalSnapshot: ModuleInfo | undefined;\n globalSnapshot: ReturnType<typeof getGlobalSnapshot>;\n remoteSnapshot: GlobalModuleInfo[string] | undefined;\n } {\n return getGlobalRemoteInfo(moduleInfo, this.HostInstance);\n }\n\n private async getManifestJson(\n manifestUrl: string,\n moduleInfo: Remote,\n extraOptions: Record<string, any>,\n ): Promise<ModuleInfo> {\n const getManifest = async (): Promise<Manifest> => {\n let manifestJson: Manifest | undefined =\n this.manifestCache.get(manifestUrl);\n if (manifestJson) {\n return manifestJson;\n }\n try {\n let res = await this.loaderHook.lifecycle.fetch.emit(manifestUrl, {});\n if (!res || !(res instanceof Response)) {\n res = await fetch(manifestUrl, {});\n }\n manifestJson = (await res.json()) as Manifest;\n } catch (err) {\n manifestJson =\n (await this.HostInstance.remoteHandler.hooks.lifecycle.errorLoadRemote.emit(\n {\n id: manifestUrl,\n error: err,\n from: 'runtime',\n lifecycle: 'afterResolve',\n origin: this.HostInstance,\n },\n )) as Manifest | undefined;\n\n if (!manifestJson) {\n delete this.manifestLoading[manifestUrl];\n error(\n RUNTIME_003,\n runtimeDescMap,\n {\n manifestUrl,\n moduleName: moduleInfo.name,\n hostName: this.HostInstance.options.name,\n },\n `${err}`,\n optionsToMFContext(this.HostInstance.options),\n );\n }\n }\n\n assert(\n manifestJson.metaData && manifestJson.exposes && manifestJson.shared,\n `\"${manifestUrl}\" is not a valid federation manifest for remote \"${moduleInfo.name}\". Missing required fields: ${[!manifestJson.metaData && 'metaData', !manifestJson.exposes && 'exposes', !manifestJson.shared && 'shared'].filter(Boolean).join(', ')}.`,\n );\n this.manifestCache.set(manifestUrl, manifestJson);\n return manifestJson;\n };\n\n const asyncLoadProcess = async () => {\n const manifestJson = await getManifest();\n const remoteSnapshot = generateSnapshotFromManifest(manifestJson, {\n version: manifestUrl,\n });\n\n const { remoteSnapshot: remoteSnapshotRes } =\n await this.hooks.lifecycle.loadRemoteSnapshot.emit({\n options: this.HostInstance.options,\n moduleInfo,\n manifestJson,\n remoteSnapshot,\n manifestUrl,\n from: 'manifest',\n });\n return remoteSnapshotRes;\n };\n\n if (!this.manifestLoading[manifestUrl]) {\n this.manifestLoading[manifestUrl] = asyncLoadProcess().then((res) => res);\n }\n return this.manifestLoading[manifestUrl];\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"SnapshotHandler.js","names":[],"sources":["../../../src/plugins/snapshot/SnapshotHandler.ts"],"sourcesContent":["import {\n GlobalModuleInfo,\n Manifest,\n ModuleInfo,\n generateSnapshotFromManifest,\n isManifestProvider,\n isBrowserEnvValue,\n} from '@module-federation/sdk';\nimport {\n RUNTIME_003,\n RUNTIME_007,\n runtimeDescMap,\n} from '@module-federation/error-codes';\nimport { Options, Remote } from '../../type';\nimport {\n isRemoteInfoWithEntry,\n error,\n optionsToMFContext,\n getRemoteInfo,\n} from '../../utils';\nimport {\n getGlobalSnapshot,\n setGlobalSnapshotInfoByModuleInfo,\n Global,\n addGlobalSnapshot,\n getGlobalSnapshotInfoByModuleInfo,\n getInfoWithoutType,\n} from '../../global';\nimport { PluginSystem, AsyncHook, AsyncWaterfallHook } from '../../utils/hooks';\nimport { ModuleFederation } from '../../core';\nimport { assert } from '../../utils/logger';\n\nexport function getGlobalRemoteInfo(\n moduleInfo: Remote,\n origin: ModuleFederation,\n): {\n hostGlobalSnapshot: ModuleInfo | undefined;\n globalSnapshot: ReturnType<typeof getGlobalSnapshot>;\n remoteSnapshot: GlobalModuleInfo[string] | undefined;\n} {\n const hostGlobalSnapshot = getGlobalSnapshotInfoByModuleInfo({\n name: origin.name,\n version: origin.options.version,\n });\n\n // get remote detail info from global\n const globalRemoteInfo =\n hostGlobalSnapshot &&\n 'remotesInfo' in hostGlobalSnapshot &&\n hostGlobalSnapshot.remotesInfo &&\n getInfoWithoutType(hostGlobalSnapshot.remotesInfo, moduleInfo.name).value;\n\n if (globalRemoteInfo && globalRemoteInfo.matchedVersion) {\n return {\n hostGlobalSnapshot,\n globalSnapshot: getGlobalSnapshot(),\n remoteSnapshot: getGlobalSnapshotInfoByModuleInfo({\n name: moduleInfo.name,\n version: globalRemoteInfo.matchedVersion,\n }),\n };\n }\n\n return {\n hostGlobalSnapshot: undefined,\n globalSnapshot: getGlobalSnapshot(),\n remoteSnapshot: getGlobalSnapshotInfoByModuleInfo({\n name: moduleInfo.name,\n version: 'version' in moduleInfo ? moduleInfo.version : undefined,\n }),\n };\n}\n\nexport class SnapshotHandler {\n loadingHostSnapshot: Promise<GlobalModuleInfo | void> | null = null;\n HostInstance: ModuleFederation;\n manifestCache: Map<string, Manifest> = new Map();\n hooks = new PluginSystem({\n beforeLoadRemoteSnapshot: new AsyncHook<\n [\n {\n options: Options;\n moduleInfo: Remote;\n },\n ],\n void\n >('beforeLoadRemoteSnapshot'),\n loadSnapshot: new AsyncWaterfallHook<{\n options: Options;\n moduleInfo: Remote;\n hostGlobalSnapshot: GlobalModuleInfo[string] | undefined;\n globalSnapshot: ReturnType<typeof getGlobalSnapshot>;\n remoteSnapshot?: GlobalModuleInfo[string] | undefined;\n }>('loadGlobalSnapshot'),\n loadRemoteSnapshot: new AsyncWaterfallHook<{\n options: Options;\n moduleInfo: Remote;\n manifestJson?: Manifest;\n manifestUrl?: string;\n remoteSnapshot: ModuleInfo;\n from: 'global' | 'manifest';\n }>('loadRemoteSnapshot'),\n afterLoadSnapshot: new AsyncWaterfallHook<{\n id?: string;\n host: ModuleFederation;\n options: Options;\n moduleInfo: Remote;\n remoteSnapshot: ModuleInfo;\n }>('afterLoadSnapshot'),\n });\n loaderHook: ModuleFederation['loaderHook'];\n manifestLoading: Record<string, Promise<ModuleInfo>> =\n Global.__FEDERATION__.__MANIFEST_LOADING__;\n\n constructor(HostInstance: ModuleFederation) {\n this.HostInstance = HostInstance;\n this.loaderHook = HostInstance.loaderHook;\n }\n\n // eslint-disable-next-line max-lines-per-function\n async loadRemoteSnapshotInfo({\n moduleInfo,\n id,\n expose,\n }: {\n moduleInfo: Remote;\n id?: string;\n expose?: string;\n }):\n | Promise<{\n remoteSnapshot: ModuleInfo;\n globalSnapshot: GlobalModuleInfo;\n }>\n | never {\n const { options } = this.HostInstance;\n\n await this.hooks.lifecycle.beforeLoadRemoteSnapshot.emit({\n options,\n moduleInfo,\n });\n\n let hostSnapshot = getGlobalSnapshotInfoByModuleInfo({\n name: this.HostInstance.options.name,\n version: this.HostInstance.options.version,\n });\n\n if (!hostSnapshot) {\n hostSnapshot = {\n version: this.HostInstance.options.version || '',\n remoteEntry: '',\n remotesInfo: {},\n };\n addGlobalSnapshot({\n [this.HostInstance.options.name]: hostSnapshot,\n });\n }\n\n // 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.\n // 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.\n if (\n hostSnapshot &&\n 'remotesInfo' in hostSnapshot &&\n !getInfoWithoutType(hostSnapshot.remotesInfo, moduleInfo.name).value\n ) {\n if ('version' in moduleInfo || 'entry' in moduleInfo) {\n hostSnapshot.remotesInfo = {\n ...hostSnapshot?.remotesInfo,\n [moduleInfo.name]: {\n matchedVersion:\n 'version' in moduleInfo ? moduleInfo.version : moduleInfo.entry,\n },\n };\n }\n }\n\n const { hostGlobalSnapshot, remoteSnapshot, globalSnapshot } =\n this.getGlobalRemoteInfo(moduleInfo);\n const {\n remoteSnapshot: globalRemoteSnapshot,\n globalSnapshot: globalSnapshotRes,\n } = await this.hooks.lifecycle.loadSnapshot.emit({\n options,\n moduleInfo,\n hostGlobalSnapshot,\n remoteSnapshot,\n globalSnapshot,\n });\n\n let mSnapshot;\n let gSnapshot;\n // global snapshot includes manifest or module info includes manifest\n if (globalRemoteSnapshot) {\n if (isManifestProvider(globalRemoteSnapshot)) {\n const remoteEntry = isBrowserEnvValue\n ? globalRemoteSnapshot.remoteEntry\n : globalRemoteSnapshot.ssrRemoteEntry ||\n globalRemoteSnapshot.remoteEntry ||\n '';\n const moduleSnapshot = await this.getManifestJson(\n remoteEntry,\n moduleInfo,\n {},\n );\n // eslint-disable-next-line @typescript-eslint/no-shadow\n const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(\n {\n ...moduleInfo,\n // The global remote may be overridden\n // Therefore, set the snapshot key to the global address of the actual request\n entry: remoteEntry,\n },\n moduleSnapshot,\n );\n mSnapshot = moduleSnapshot;\n gSnapshot = globalSnapshotRes;\n } else {\n const { remoteSnapshot: remoteSnapshotRes } =\n await this.hooks.lifecycle.loadRemoteSnapshot.emit({\n options: this.HostInstance.options,\n moduleInfo,\n remoteSnapshot: globalRemoteSnapshot,\n from: 'global',\n });\n mSnapshot = remoteSnapshotRes;\n gSnapshot = globalSnapshotRes;\n }\n } else {\n if (isRemoteInfoWithEntry(moduleInfo)) {\n // get from manifest.json and merge remote info from remote server\n const moduleSnapshot = await this.getManifestJson(\n moduleInfo.entry,\n moduleInfo,\n {},\n );\n // eslint-disable-next-line @typescript-eslint/no-shadow\n const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(\n moduleInfo,\n moduleSnapshot,\n );\n const { remoteSnapshot: remoteSnapshotRes } =\n await this.hooks.lifecycle.loadRemoteSnapshot.emit({\n options: this.HostInstance.options,\n moduleInfo,\n remoteSnapshot: moduleSnapshot,\n from: 'global',\n });\n\n mSnapshot = remoteSnapshotRes;\n gSnapshot = globalSnapshotRes;\n } else {\n error(\n RUNTIME_007,\n runtimeDescMap,\n {\n remoteName: moduleInfo.name,\n remoteVersion: moduleInfo.version,\n hostName: this.HostInstance.options.name,\n globalSnapshot: JSON.stringify(globalSnapshotRes),\n },\n undefined,\n optionsToMFContext(this.HostInstance.options),\n );\n }\n }\n\n await this.hooks.lifecycle.afterLoadSnapshot.emit({\n id,\n host: this.HostInstance,\n options,\n moduleInfo,\n remoteSnapshot: mSnapshot,\n });\n\n return {\n remoteSnapshot: mSnapshot,\n globalSnapshot: gSnapshot,\n };\n }\n\n getGlobalRemoteInfo(moduleInfo: Remote): {\n hostGlobalSnapshot: ModuleInfo | undefined;\n globalSnapshot: ReturnType<typeof getGlobalSnapshot>;\n remoteSnapshot: GlobalModuleInfo[string] | undefined;\n } {\n return getGlobalRemoteInfo(moduleInfo, this.HostInstance);\n }\n\n private async getManifestJson(\n manifestUrl: string,\n moduleInfo: Remote,\n extraOptions: Record<string, any>,\n ): Promise<ModuleInfo> {\n const getManifest = async (): Promise<Manifest> => {\n let manifestJson: Manifest | undefined =\n this.manifestCache.get(manifestUrl);\n if (manifestJson) {\n return manifestJson;\n }\n try {\n let res = await this.loaderHook.lifecycle.fetch.emit(\n manifestUrl,\n {},\n getRemoteInfo(moduleInfo),\n );\n if (!res || !(res instanceof Response)) {\n res = await fetch(manifestUrl, {});\n }\n manifestJson = (await res.json()) as Manifest;\n } catch (err) {\n manifestJson =\n (await this.HostInstance.remoteHandler.hooks.lifecycle.errorLoadRemote.emit(\n {\n id: manifestUrl,\n error: err,\n from: 'runtime',\n lifecycle: 'afterResolve',\n origin: this.HostInstance,\n },\n )) as Manifest | undefined;\n\n if (!manifestJson) {\n delete this.manifestLoading[manifestUrl];\n error(\n RUNTIME_003,\n runtimeDescMap,\n {\n manifestUrl,\n moduleName: moduleInfo.name,\n hostName: this.HostInstance.options.name,\n },\n `${err}`,\n optionsToMFContext(this.HostInstance.options),\n );\n }\n }\n\n assert(\n manifestJson.metaData && manifestJson.exposes && manifestJson.shared,\n `\"${manifestUrl}\" is not a valid federation manifest for remote \"${moduleInfo.name}\". Missing required fields: ${[!manifestJson.metaData && 'metaData', !manifestJson.exposes && 'exposes', !manifestJson.shared && 'shared'].filter(Boolean).join(', ')}.`,\n );\n this.manifestCache.set(manifestUrl, manifestJson);\n return manifestJson;\n };\n\n const asyncLoadProcess = async () => {\n const manifestJson = await getManifest();\n const remoteSnapshot = generateSnapshotFromManifest(manifestJson, {\n version: manifestUrl,\n });\n\n const { remoteSnapshot: remoteSnapshotRes } =\n await this.hooks.lifecycle.loadRemoteSnapshot.emit({\n options: this.HostInstance.options,\n moduleInfo,\n manifestJson,\n remoteSnapshot,\n manifestUrl,\n from: 'manifest',\n });\n return remoteSnapshotRes;\n };\n\n if (!this.manifestLoading[manifestUrl]) {\n this.manifestLoading[manifestUrl] = asyncLoadProcess().then((res) => res);\n }\n return this.manifestLoading[manifestUrl];\n }\n}\n"],"mappings":"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"}
@@ -9,7 +9,6 @@ interface PreloadRemoteArgs {
9
9
  share?: boolean;
10
10
  depsRemote?: boolean | Array<depsPreloadArg>;
11
11
  filter?: (assetUrl: string) => boolean;
12
- prefetchInterface?: boolean;
13
12
  }
14
13
  type PreloadConfig = PreloadRemoteArgs;
15
14
  type PreloadOptions = Array<{
@@ -15,5 +15,5 @@ declare class PluginSystem<T extends Record<string, any>> {
15
15
  removePlugin(pluginName: string): void;
16
16
  }
17
17
  //#endregion
18
- export { PluginSystem };
18
+ export { Plugin, PluginSystem };
19
19
  //# sourceMappingURL=pluginSystem.d.ts.map
@@ -41,7 +41,7 @@ function handleRemoteEntryLoaded(name, globalName, entry) {
41
41
  });
42
42
  return entryExports;
43
43
  }
44
- async function loadEntryScript({ name, globalName, entry, loaderHook, getEntryUrl }) {
44
+ async function loadEntryScript({ name, globalName, entry, remoteInfo, loaderHook, getEntryUrl }) {
45
45
  const { entryExports: remoteEntryExports } = require_global.getRemoteEntryExports(name, globalName);
46
46
  if (remoteEntryExports) return remoteEntryExports;
47
47
  const url = getEntryUrl ? getEntryUrl(entry) : entry;
@@ -50,7 +50,8 @@ async function loadEntryScript({ name, globalName, entry, loaderHook, getEntryUr
50
50
  createScriptHook: (url, attrs) => {
51
51
  const res = loaderHook.lifecycle.createScript.emit({
52
52
  url,
53
- attrs
53
+ attrs,
54
+ remoteInfo
54
55
  });
55
56
  if (!res) return;
56
57
  if (res instanceof HTMLScriptElement) return res;
@@ -82,6 +83,7 @@ async function loadEntryDom({ remoteInfo, remoteEntryExports, loaderHook, getEnt
82
83
  entry,
83
84
  globalName,
84
85
  name,
86
+ remoteInfo,
85
87
  loaderHook,
86
88
  getEntryUrl
87
89
  });
@@ -100,7 +102,8 @@ async function loadEntryNode({ remoteInfo, loaderHook }) {
100
102
  loaderHook: { createScriptHook: (url, attrs = {}) => {
101
103
  const res = loaderHook.lifecycle.createScript.emit({
102
104
  url,
103
- attrs
105
+ attrs,
106
+ remoteInfo
104
107
  });
105
108
  if (!res) return;
106
109
  if ("url" in res) return res;
@@ -1 +1 @@
1
- {"version":3,"file":"load.cjs","names":["getRemoteEntryExports","RUNTIME_001","runtimeDescMap","RUNTIME_008","globalLoading","isBrowserEnvValue","DEFAULT_REMOTE_TYPE","DEFAULT_SCOPE"],"sources":["../../src/utils/load.ts"],"sourcesContent":["import {\n loadScript,\n loadScriptNode,\n composeKeyWithSeparator,\n isBrowserEnvValue,\n} from '@module-federation/sdk';\nimport { DEFAULT_REMOTE_TYPE, DEFAULT_SCOPE } from '../constant';\nimport { ModuleFederation } from '../core';\nimport { globalLoading, getRemoteEntryExports } from '../global';\nimport { Remote, RemoteEntryExports, RemoteInfo } from '../type';\nimport { assert, error } from './logger';\nimport {\n RUNTIME_001,\n RUNTIME_008,\n runtimeDescMap,\n} from '@module-federation/error-codes';\n\n// Declare the ENV_TARGET constant that will be defined by DefinePlugin\ndeclare const ENV_TARGET: 'web' | 'node';\nconst importCallback = '.then(callbacks[0]).catch(callbacks[1])';\n\nasync function loadEsmEntry({\n entry,\n remoteEntryExports,\n}: {\n entry: string;\n remoteEntryExports: RemoteEntryExports | undefined;\n}): Promise<RemoteEntryExports> {\n return new Promise<RemoteEntryExports>((resolve, reject) => {\n try {\n if (!remoteEntryExports) {\n if (typeof FEDERATION_ALLOW_NEW_FUNCTION !== 'undefined') {\n new Function('callbacks', `import(\"${entry}\")${importCallback}`)([\n resolve,\n reject,\n ]);\n } else {\n import(/* webpackIgnore: true */ /* @vite-ignore */ entry)\n .then(resolve)\n .catch(reject);\n }\n } else {\n resolve(remoteEntryExports);\n }\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n error(`Failed to load ESM entry from \"${entry}\". ${msg}`);\n }\n });\n}\n\nasync function loadSystemJsEntry({\n entry,\n remoteEntryExports,\n}: {\n entry: string;\n remoteEntryExports: RemoteEntryExports | undefined;\n}): Promise<RemoteEntryExports> {\n return new Promise<RemoteEntryExports>((resolve, reject) => {\n try {\n if (!remoteEntryExports) {\n //@ts-ignore\n if (typeof __system_context__ === 'undefined') {\n //@ts-ignore\n System.import(entry).then(resolve).catch(reject);\n } else {\n new Function(\n 'callbacks',\n `System.import(\"${entry}\")${importCallback}`,\n )([resolve, reject]);\n }\n } else {\n resolve(remoteEntryExports);\n }\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n error(`Failed to load SystemJS entry from \"${entry}\". ${msg}`);\n }\n });\n}\n\nfunction handleRemoteEntryLoaded(\n name: string,\n globalName: string,\n entry: string,\n): RemoteEntryExports {\n const { remoteEntryKey, entryExports } = getRemoteEntryExports(\n name,\n globalName,\n );\n\n if (!entryExports) {\n error(RUNTIME_001, runtimeDescMap, {\n remoteName: name,\n remoteEntryUrl: entry,\n remoteEntryKey,\n });\n }\n\n return entryExports;\n}\n\nasync function loadEntryScript({\n name,\n globalName,\n entry,\n loaderHook,\n getEntryUrl,\n}: {\n name: string;\n globalName: string;\n entry: string;\n loaderHook: ModuleFederation['loaderHook'];\n getEntryUrl?: (url: string) => string;\n}): Promise<RemoteEntryExports> {\n const { entryExports: remoteEntryExports } = getRemoteEntryExports(\n name,\n globalName,\n );\n\n if (remoteEntryExports) {\n return remoteEntryExports;\n }\n\n // if getEntryUrl is passed, use the getEntryUrl to get the entry url\n const url = getEntryUrl ? getEntryUrl(entry) : entry;\n return loadScript(url, {\n attrs: {},\n createScriptHook: (url, attrs) => {\n const res = loaderHook.lifecycle.createScript.emit({ url, attrs });\n\n if (!res) return;\n\n if (res instanceof HTMLScriptElement) {\n return res;\n }\n\n if ('script' in res || 'timeout' in res) {\n return res;\n }\n\n return;\n },\n }).then(\n () => {\n // loadScript resolved: script was fetched, executed without throwing, and\n // did not trigger a ScriptExecutionError listener. Now verify the global was registered.\n return handleRemoteEntryLoaded(name, globalName, entry);\n },\n (loadError: unknown) => {\n // loadScript rejected — one of three causes, all with descriptive messages:\n // ScriptNetworkError — URL unreachable, 404, CORS, etc.\n // ScriptExecutionError — script fetched OK but IIFE threw during execution\n // timeout — script took too long to load\n // Errors thrown inside handleRemoteEntryLoaded above are NOT caught here.\n const originalMsg =\n loadError instanceof Error ? loadError.message : String(loadError);\n error(\n RUNTIME_008,\n runtimeDescMap,\n {\n remoteName: name,\n resourceUrl: url,\n },\n originalMsg,\n );\n },\n );\n}\nasync function loadEntryDom({\n remoteInfo,\n remoteEntryExports,\n loaderHook,\n getEntryUrl,\n}: {\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports;\n loaderHook: ModuleFederation['loaderHook'];\n getEntryUrl?: (url: string) => string;\n}) {\n const { entry, entryGlobalName: globalName, name, type } = remoteInfo;\n switch (type) {\n case 'esm':\n case 'module':\n return loadEsmEntry({ entry, remoteEntryExports });\n case 'system':\n return loadSystemJsEntry({ entry, remoteEntryExports });\n default:\n return loadEntryScript({\n entry,\n globalName,\n name,\n loaderHook,\n getEntryUrl,\n });\n }\n}\n\nasync function loadEntryNode({\n remoteInfo,\n loaderHook,\n}: {\n remoteInfo: RemoteInfo;\n loaderHook: ModuleFederation['loaderHook'];\n}) {\n const { entry, entryGlobalName: globalName, name, type } = remoteInfo;\n const { entryExports: remoteEntryExports } = getRemoteEntryExports(\n name,\n globalName,\n );\n\n if (remoteEntryExports) {\n return remoteEntryExports;\n }\n\n return loadScriptNode(entry, {\n attrs: { name, globalName, type },\n loaderHook: {\n createScriptHook: (url: string, attrs: Record<string, any> = {}) => {\n const res = loaderHook.lifecycle.createScript.emit({ url, attrs });\n\n if (!res) return;\n\n if ('url' in res) {\n return res;\n }\n\n return;\n },\n },\n })\n .then(() => {\n return handleRemoteEntryLoaded(name, globalName, entry);\n })\n .catch((e) => {\n const msg = e instanceof Error ? e.message : String(e);\n error(\n `Failed to load Node.js entry for remote \"${name}\" from \"${entry}\". ${msg}`,\n );\n });\n}\n\nexport function getRemoteEntryUniqueKey(remoteInfo: RemoteInfo): string {\n const { entry, name } = remoteInfo;\n return composeKeyWithSeparator(name, entry);\n}\n\nexport async function getRemoteEntry(params: {\n origin: ModuleFederation;\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports | undefined;\n getEntryUrl?: (url: string) => string;\n _inErrorHandling?: boolean; // Add flag to prevent recursion\n}): Promise<RemoteEntryExports | false | void> {\n const {\n origin,\n remoteEntryExports,\n remoteInfo,\n getEntryUrl,\n _inErrorHandling = false,\n } = params;\n const uniqueKey = getRemoteEntryUniqueKey(remoteInfo);\n if (remoteEntryExports) {\n return remoteEntryExports;\n }\n\n if (!globalLoading[uniqueKey]) {\n const loadEntryHook = origin.remoteHandler.hooks.lifecycle.loadEntry;\n const loaderHook = origin.loaderHook;\n\n globalLoading[uniqueKey] = loadEntryHook\n .emit({\n loaderHook,\n remoteInfo,\n remoteEntryExports,\n })\n .then((res) => {\n if (res) {\n return res;\n }\n // Use ENV_TARGET if defined, otherwise fallback to isBrowserEnvValue\n const isWebEnvironment =\n typeof ENV_TARGET !== 'undefined'\n ? ENV_TARGET === 'web'\n : isBrowserEnvValue;\n\n return isWebEnvironment\n ? loadEntryDom({\n remoteInfo,\n remoteEntryExports,\n loaderHook,\n getEntryUrl,\n })\n : loadEntryNode({ remoteInfo, loaderHook });\n })\n .catch(async (err) => {\n const uniqueKey = getRemoteEntryUniqueKey(remoteInfo);\n // ScriptExecutionError means the script downloaded fine but its IIFE\n // threw at runtime — retrying would reproduce the same error, so exclude it.\n const isScriptExecutionError =\n err instanceof Error && err.message.includes('ScriptExecutionError');\n const isScriptLoadError =\n err instanceof Error &&\n err.message.includes(RUNTIME_008) &&\n !isScriptExecutionError;\n\n if (isScriptLoadError && !_inErrorHandling) {\n const wrappedGetRemoteEntry = (\n params: Parameters<typeof getRemoteEntry>[0],\n ) => {\n return getRemoteEntry({ ...params, _inErrorHandling: true });\n };\n\n const RemoteEntryExports =\n await origin.loaderHook.lifecycle.loadEntryError.emit({\n getRemoteEntry: wrappedGetRemoteEntry,\n origin,\n remoteInfo: remoteInfo,\n remoteEntryExports,\n globalLoading,\n uniqueKey,\n });\n\n if (RemoteEntryExports) {\n return RemoteEntryExports;\n }\n }\n throw err;\n });\n }\n\n return globalLoading[uniqueKey];\n}\n\nexport function getRemoteInfo(remote: Remote): RemoteInfo {\n return {\n ...remote,\n entry: 'entry' in remote ? remote.entry : '',\n type: remote.type || DEFAULT_REMOTE_TYPE,\n entryGlobalName: remote.entryGlobalName || remote.name,\n shareScope: remote.shareScope || DEFAULT_SCOPE,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"load.cjs","names":["getRemoteEntryExports","RUNTIME_001","runtimeDescMap","RUNTIME_008","globalLoading","isBrowserEnvValue","DEFAULT_REMOTE_TYPE","DEFAULT_SCOPE"],"sources":["../../src/utils/load.ts"],"sourcesContent":["import {\n loadScript,\n loadScriptNode,\n composeKeyWithSeparator,\n isBrowserEnvValue,\n} from '@module-federation/sdk';\nimport { DEFAULT_REMOTE_TYPE, DEFAULT_SCOPE } from '../constant';\nimport { ModuleFederation } from '../core';\nimport { globalLoading, getRemoteEntryExports } from '../global';\nimport { Remote, RemoteEntryExports, RemoteInfo } from '../type';\nimport { assert, error } from './logger';\nimport {\n RUNTIME_001,\n RUNTIME_008,\n runtimeDescMap,\n} from '@module-federation/error-codes';\n\n// Declare the ENV_TARGET constant that will be defined by DefinePlugin\ndeclare const ENV_TARGET: 'web' | 'node';\nconst importCallback = '.then(callbacks[0]).catch(callbacks[1])';\n\nasync function loadEsmEntry({\n entry,\n remoteEntryExports,\n}: {\n entry: string;\n remoteEntryExports: RemoteEntryExports | undefined;\n}): Promise<RemoteEntryExports> {\n return new Promise<RemoteEntryExports>((resolve, reject) => {\n try {\n if (!remoteEntryExports) {\n if (typeof FEDERATION_ALLOW_NEW_FUNCTION !== 'undefined') {\n new Function('callbacks', `import(\"${entry}\")${importCallback}`)([\n resolve,\n reject,\n ]);\n } else {\n import(/* webpackIgnore: true */ /* @vite-ignore */ entry)\n .then(resolve)\n .catch(reject);\n }\n } else {\n resolve(remoteEntryExports);\n }\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n error(`Failed to load ESM entry from \"${entry}\". ${msg}`);\n }\n });\n}\n\nasync function loadSystemJsEntry({\n entry,\n remoteEntryExports,\n}: {\n entry: string;\n remoteEntryExports: RemoteEntryExports | undefined;\n}): Promise<RemoteEntryExports> {\n return new Promise<RemoteEntryExports>((resolve, reject) => {\n try {\n if (!remoteEntryExports) {\n //@ts-ignore\n if (typeof __system_context__ === 'undefined') {\n //@ts-ignore\n System.import(entry).then(resolve).catch(reject);\n } else {\n new Function(\n 'callbacks',\n `System.import(\"${entry}\")${importCallback}`,\n )([resolve, reject]);\n }\n } else {\n resolve(remoteEntryExports);\n }\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n error(`Failed to load SystemJS entry from \"${entry}\". ${msg}`);\n }\n });\n}\n\nfunction handleRemoteEntryLoaded(\n name: string,\n globalName: string,\n entry: string,\n): RemoteEntryExports {\n const { remoteEntryKey, entryExports } = getRemoteEntryExports(\n name,\n globalName,\n );\n\n if (!entryExports) {\n error(RUNTIME_001, runtimeDescMap, {\n remoteName: name,\n remoteEntryUrl: entry,\n remoteEntryKey,\n });\n }\n\n return entryExports;\n}\n\nasync function loadEntryScript({\n name,\n globalName,\n entry,\n remoteInfo,\n loaderHook,\n getEntryUrl,\n}: {\n name: string;\n globalName: string;\n entry: string;\n remoteInfo: RemoteInfo;\n loaderHook: ModuleFederation['loaderHook'];\n getEntryUrl?: (url: string) => string;\n}): Promise<RemoteEntryExports> {\n const { entryExports: remoteEntryExports } = getRemoteEntryExports(\n name,\n globalName,\n );\n\n if (remoteEntryExports) {\n return remoteEntryExports;\n }\n\n // if getEntryUrl is passed, use the getEntryUrl to get the entry url\n const url = getEntryUrl ? getEntryUrl(entry) : entry;\n return loadScript(url, {\n attrs: {},\n createScriptHook: (url, attrs) => {\n const res = loaderHook.lifecycle.createScript.emit({\n url,\n attrs,\n remoteInfo,\n });\n\n if (!res) return;\n\n if (res instanceof HTMLScriptElement) {\n return res;\n }\n\n if ('script' in res || 'timeout' in res) {\n return res;\n }\n\n return;\n },\n }).then(\n () => {\n // loadScript resolved: script was fetched, executed without throwing, and\n // did not trigger a ScriptExecutionError listener. Now verify the global was registered.\n return handleRemoteEntryLoaded(name, globalName, entry);\n },\n (loadError: unknown) => {\n // loadScript rejected — one of three causes, all with descriptive messages:\n // ScriptNetworkError — URL unreachable, 404, CORS, etc.\n // ScriptExecutionError — script fetched OK but IIFE threw during execution\n // timeout — script took too long to load\n // Errors thrown inside handleRemoteEntryLoaded above are NOT caught here.\n const originalMsg =\n loadError instanceof Error ? loadError.message : String(loadError);\n error(\n RUNTIME_008,\n runtimeDescMap,\n {\n remoteName: name,\n resourceUrl: url,\n },\n originalMsg,\n );\n },\n );\n}\nasync function loadEntryDom({\n remoteInfo,\n remoteEntryExports,\n loaderHook,\n getEntryUrl,\n}: {\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports;\n loaderHook: ModuleFederation['loaderHook'];\n getEntryUrl?: (url: string) => string;\n}) {\n const { entry, entryGlobalName: globalName, name, type } = remoteInfo;\n switch (type) {\n case 'esm':\n case 'module':\n return loadEsmEntry({ entry, remoteEntryExports });\n case 'system':\n return loadSystemJsEntry({ entry, remoteEntryExports });\n default:\n return loadEntryScript({\n entry,\n globalName,\n name,\n remoteInfo,\n loaderHook,\n getEntryUrl,\n });\n }\n}\n\nasync function loadEntryNode({\n remoteInfo,\n loaderHook,\n}: {\n remoteInfo: RemoteInfo;\n loaderHook: ModuleFederation['loaderHook'];\n}) {\n const { entry, entryGlobalName: globalName, name, type } = remoteInfo;\n const { entryExports: remoteEntryExports } = getRemoteEntryExports(\n name,\n globalName,\n );\n\n if (remoteEntryExports) {\n return remoteEntryExports;\n }\n\n return loadScriptNode(entry, {\n attrs: { name, globalName, type },\n loaderHook: {\n createScriptHook: (url: string, attrs: Record<string, any> = {}) => {\n const res = loaderHook.lifecycle.createScript.emit({\n url,\n attrs,\n remoteInfo,\n });\n\n if (!res) return;\n\n if ('url' in res) {\n return res;\n }\n\n return;\n },\n },\n })\n .then(() => {\n return handleRemoteEntryLoaded(name, globalName, entry);\n })\n .catch((e) => {\n const msg = e instanceof Error ? e.message : String(e);\n error(\n `Failed to load Node.js entry for remote \"${name}\" from \"${entry}\". ${msg}`,\n );\n });\n}\n\nexport function getRemoteEntryUniqueKey(remoteInfo: RemoteInfo): string {\n const { entry, name } = remoteInfo;\n return composeKeyWithSeparator(name, entry);\n}\n\nexport async function getRemoteEntry(params: {\n origin: ModuleFederation;\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports | undefined;\n getEntryUrl?: (url: string) => string;\n _inErrorHandling?: boolean; // Add flag to prevent recursion\n}): Promise<RemoteEntryExports | false | void> {\n const {\n origin,\n remoteEntryExports,\n remoteInfo,\n getEntryUrl,\n _inErrorHandling = false,\n } = params;\n const uniqueKey = getRemoteEntryUniqueKey(remoteInfo);\n if (remoteEntryExports) {\n return remoteEntryExports;\n }\n\n if (!globalLoading[uniqueKey]) {\n const loadEntryHook = origin.remoteHandler.hooks.lifecycle.loadEntry;\n const loaderHook = origin.loaderHook;\n\n globalLoading[uniqueKey] = loadEntryHook\n .emit({\n loaderHook,\n remoteInfo,\n remoteEntryExports,\n })\n .then((res) => {\n if (res) {\n return res;\n }\n // Use ENV_TARGET if defined, otherwise fallback to isBrowserEnvValue\n const isWebEnvironment =\n typeof ENV_TARGET !== 'undefined'\n ? ENV_TARGET === 'web'\n : isBrowserEnvValue;\n\n return isWebEnvironment\n ? loadEntryDom({\n remoteInfo,\n remoteEntryExports,\n loaderHook,\n getEntryUrl,\n })\n : loadEntryNode({ remoteInfo, loaderHook });\n })\n .catch(async (err) => {\n const uniqueKey = getRemoteEntryUniqueKey(remoteInfo);\n // ScriptExecutionError means the script downloaded fine but its IIFE\n // threw at runtime — retrying would reproduce the same error, so exclude it.\n const isScriptExecutionError =\n err instanceof Error && err.message.includes('ScriptExecutionError');\n const isScriptLoadError =\n err instanceof Error &&\n err.message.includes(RUNTIME_008) &&\n !isScriptExecutionError;\n\n if (isScriptLoadError && !_inErrorHandling) {\n const wrappedGetRemoteEntry = (\n params: Parameters<typeof getRemoteEntry>[0],\n ) => {\n return getRemoteEntry({ ...params, _inErrorHandling: true });\n };\n\n const RemoteEntryExports =\n await origin.loaderHook.lifecycle.loadEntryError.emit({\n getRemoteEntry: wrappedGetRemoteEntry,\n origin,\n remoteInfo: remoteInfo,\n remoteEntryExports,\n globalLoading,\n uniqueKey,\n });\n\n if (RemoteEntryExports) {\n return RemoteEntryExports;\n }\n }\n throw err;\n });\n }\n\n return globalLoading[uniqueKey];\n}\n\nexport function getRemoteInfo(remote: Remote): RemoteInfo {\n return {\n ...remote,\n entry: 'entry' in remote ? remote.entry : '',\n type: remote.type || DEFAULT_REMOTE_TYPE,\n entryGlobalName: remote.entryGlobalName || remote.name,\n shareScope: remote.shareScope || DEFAULT_SCOPE,\n };\n}\n"],"mappings":"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"}
@@ -41,7 +41,7 @@ function handleRemoteEntryLoaded(name, globalName, entry) {
41
41
  });
42
42
  return entryExports;
43
43
  }
44
- async function loadEntryScript({ name, globalName, entry, loaderHook, getEntryUrl }) {
44
+ async function loadEntryScript({ name, globalName, entry, remoteInfo, loaderHook, getEntryUrl }) {
45
45
  const { entryExports: remoteEntryExports } = getRemoteEntryExports(name, globalName);
46
46
  if (remoteEntryExports) return remoteEntryExports;
47
47
  const url = getEntryUrl ? getEntryUrl(entry) : entry;
@@ -50,7 +50,8 @@ async function loadEntryScript({ name, globalName, entry, loaderHook, getEntryUr
50
50
  createScriptHook: (url, attrs) => {
51
51
  const res = loaderHook.lifecycle.createScript.emit({
52
52
  url,
53
- attrs
53
+ attrs,
54
+ remoteInfo
54
55
  });
55
56
  if (!res) return;
56
57
  if (res instanceof HTMLScriptElement) return res;
@@ -82,6 +83,7 @@ async function loadEntryDom({ remoteInfo, remoteEntryExports, loaderHook, getEnt
82
83
  entry,
83
84
  globalName,
84
85
  name,
86
+ remoteInfo,
85
87
  loaderHook,
86
88
  getEntryUrl
87
89
  });
@@ -100,7 +102,8 @@ async function loadEntryNode({ remoteInfo, loaderHook }) {
100
102
  loaderHook: { createScriptHook: (url, attrs = {}) => {
101
103
  const res = loaderHook.lifecycle.createScript.emit({
102
104
  url,
103
- attrs
105
+ attrs,
106
+ remoteInfo
104
107
  });
105
108
  if (!res) return;
106
109
  if ("url" in res) return res;
@@ -1 +1 @@
1
- {"version":3,"file":"load.js","names":[],"sources":["../../src/utils/load.ts"],"sourcesContent":["import {\n loadScript,\n loadScriptNode,\n composeKeyWithSeparator,\n isBrowserEnvValue,\n} from '@module-federation/sdk';\nimport { DEFAULT_REMOTE_TYPE, DEFAULT_SCOPE } from '../constant';\nimport { ModuleFederation } from '../core';\nimport { globalLoading, getRemoteEntryExports } from '../global';\nimport { Remote, RemoteEntryExports, RemoteInfo } from '../type';\nimport { assert, error } from './logger';\nimport {\n RUNTIME_001,\n RUNTIME_008,\n runtimeDescMap,\n} from '@module-federation/error-codes';\n\n// Declare the ENV_TARGET constant that will be defined by DefinePlugin\ndeclare const ENV_TARGET: 'web' | 'node';\nconst importCallback = '.then(callbacks[0]).catch(callbacks[1])';\n\nasync function loadEsmEntry({\n entry,\n remoteEntryExports,\n}: {\n entry: string;\n remoteEntryExports: RemoteEntryExports | undefined;\n}): Promise<RemoteEntryExports> {\n return new Promise<RemoteEntryExports>((resolve, reject) => {\n try {\n if (!remoteEntryExports) {\n if (typeof FEDERATION_ALLOW_NEW_FUNCTION !== 'undefined') {\n new Function('callbacks', `import(\"${entry}\")${importCallback}`)([\n resolve,\n reject,\n ]);\n } else {\n import(/* webpackIgnore: true */ /* @vite-ignore */ entry)\n .then(resolve)\n .catch(reject);\n }\n } else {\n resolve(remoteEntryExports);\n }\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n error(`Failed to load ESM entry from \"${entry}\". ${msg}`);\n }\n });\n}\n\nasync function loadSystemJsEntry({\n entry,\n remoteEntryExports,\n}: {\n entry: string;\n remoteEntryExports: RemoteEntryExports | undefined;\n}): Promise<RemoteEntryExports> {\n return new Promise<RemoteEntryExports>((resolve, reject) => {\n try {\n if (!remoteEntryExports) {\n //@ts-ignore\n if (typeof __system_context__ === 'undefined') {\n //@ts-ignore\n System.import(entry).then(resolve).catch(reject);\n } else {\n new Function(\n 'callbacks',\n `System.import(\"${entry}\")${importCallback}`,\n )([resolve, reject]);\n }\n } else {\n resolve(remoteEntryExports);\n }\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n error(`Failed to load SystemJS entry from \"${entry}\". ${msg}`);\n }\n });\n}\n\nfunction handleRemoteEntryLoaded(\n name: string,\n globalName: string,\n entry: string,\n): RemoteEntryExports {\n const { remoteEntryKey, entryExports } = getRemoteEntryExports(\n name,\n globalName,\n );\n\n if (!entryExports) {\n error(RUNTIME_001, runtimeDescMap, {\n remoteName: name,\n remoteEntryUrl: entry,\n remoteEntryKey,\n });\n }\n\n return entryExports;\n}\n\nasync function loadEntryScript({\n name,\n globalName,\n entry,\n loaderHook,\n getEntryUrl,\n}: {\n name: string;\n globalName: string;\n entry: string;\n loaderHook: ModuleFederation['loaderHook'];\n getEntryUrl?: (url: string) => string;\n}): Promise<RemoteEntryExports> {\n const { entryExports: remoteEntryExports } = getRemoteEntryExports(\n name,\n globalName,\n );\n\n if (remoteEntryExports) {\n return remoteEntryExports;\n }\n\n // if getEntryUrl is passed, use the getEntryUrl to get the entry url\n const url = getEntryUrl ? getEntryUrl(entry) : entry;\n return loadScript(url, {\n attrs: {},\n createScriptHook: (url, attrs) => {\n const res = loaderHook.lifecycle.createScript.emit({ url, attrs });\n\n if (!res) return;\n\n if (res instanceof HTMLScriptElement) {\n return res;\n }\n\n if ('script' in res || 'timeout' in res) {\n return res;\n }\n\n return;\n },\n }).then(\n () => {\n // loadScript resolved: script was fetched, executed without throwing, and\n // did not trigger a ScriptExecutionError listener. Now verify the global was registered.\n return handleRemoteEntryLoaded(name, globalName, entry);\n },\n (loadError: unknown) => {\n // loadScript rejected — one of three causes, all with descriptive messages:\n // ScriptNetworkError — URL unreachable, 404, CORS, etc.\n // ScriptExecutionError — script fetched OK but IIFE threw during execution\n // timeout — script took too long to load\n // Errors thrown inside handleRemoteEntryLoaded above are NOT caught here.\n const originalMsg =\n loadError instanceof Error ? loadError.message : String(loadError);\n error(\n RUNTIME_008,\n runtimeDescMap,\n {\n remoteName: name,\n resourceUrl: url,\n },\n originalMsg,\n );\n },\n );\n}\nasync function loadEntryDom({\n remoteInfo,\n remoteEntryExports,\n loaderHook,\n getEntryUrl,\n}: {\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports;\n loaderHook: ModuleFederation['loaderHook'];\n getEntryUrl?: (url: string) => string;\n}) {\n const { entry, entryGlobalName: globalName, name, type } = remoteInfo;\n switch (type) {\n case 'esm':\n case 'module':\n return loadEsmEntry({ entry, remoteEntryExports });\n case 'system':\n return loadSystemJsEntry({ entry, remoteEntryExports });\n default:\n return loadEntryScript({\n entry,\n globalName,\n name,\n loaderHook,\n getEntryUrl,\n });\n }\n}\n\nasync function loadEntryNode({\n remoteInfo,\n loaderHook,\n}: {\n remoteInfo: RemoteInfo;\n loaderHook: ModuleFederation['loaderHook'];\n}) {\n const { entry, entryGlobalName: globalName, name, type } = remoteInfo;\n const { entryExports: remoteEntryExports } = getRemoteEntryExports(\n name,\n globalName,\n );\n\n if (remoteEntryExports) {\n return remoteEntryExports;\n }\n\n return loadScriptNode(entry, {\n attrs: { name, globalName, type },\n loaderHook: {\n createScriptHook: (url: string, attrs: Record<string, any> = {}) => {\n const res = loaderHook.lifecycle.createScript.emit({ url, attrs });\n\n if (!res) return;\n\n if ('url' in res) {\n return res;\n }\n\n return;\n },\n },\n })\n .then(() => {\n return handleRemoteEntryLoaded(name, globalName, entry);\n })\n .catch((e) => {\n const msg = e instanceof Error ? e.message : String(e);\n error(\n `Failed to load Node.js entry for remote \"${name}\" from \"${entry}\". ${msg}`,\n );\n });\n}\n\nexport function getRemoteEntryUniqueKey(remoteInfo: RemoteInfo): string {\n const { entry, name } = remoteInfo;\n return composeKeyWithSeparator(name, entry);\n}\n\nexport async function getRemoteEntry(params: {\n origin: ModuleFederation;\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports | undefined;\n getEntryUrl?: (url: string) => string;\n _inErrorHandling?: boolean; // Add flag to prevent recursion\n}): Promise<RemoteEntryExports | false | void> {\n const {\n origin,\n remoteEntryExports,\n remoteInfo,\n getEntryUrl,\n _inErrorHandling = false,\n } = params;\n const uniqueKey = getRemoteEntryUniqueKey(remoteInfo);\n if (remoteEntryExports) {\n return remoteEntryExports;\n }\n\n if (!globalLoading[uniqueKey]) {\n const loadEntryHook = origin.remoteHandler.hooks.lifecycle.loadEntry;\n const loaderHook = origin.loaderHook;\n\n globalLoading[uniqueKey] = loadEntryHook\n .emit({\n loaderHook,\n remoteInfo,\n remoteEntryExports,\n })\n .then((res) => {\n if (res) {\n return res;\n }\n // Use ENV_TARGET if defined, otherwise fallback to isBrowserEnvValue\n const isWebEnvironment =\n typeof ENV_TARGET !== 'undefined'\n ? ENV_TARGET === 'web'\n : isBrowserEnvValue;\n\n return isWebEnvironment\n ? loadEntryDom({\n remoteInfo,\n remoteEntryExports,\n loaderHook,\n getEntryUrl,\n })\n : loadEntryNode({ remoteInfo, loaderHook });\n })\n .catch(async (err) => {\n const uniqueKey = getRemoteEntryUniqueKey(remoteInfo);\n // ScriptExecutionError means the script downloaded fine but its IIFE\n // threw at runtime — retrying would reproduce the same error, so exclude it.\n const isScriptExecutionError =\n err instanceof Error && err.message.includes('ScriptExecutionError');\n const isScriptLoadError =\n err instanceof Error &&\n err.message.includes(RUNTIME_008) &&\n !isScriptExecutionError;\n\n if (isScriptLoadError && !_inErrorHandling) {\n const wrappedGetRemoteEntry = (\n params: Parameters<typeof getRemoteEntry>[0],\n ) => {\n return getRemoteEntry({ ...params, _inErrorHandling: true });\n };\n\n const RemoteEntryExports =\n await origin.loaderHook.lifecycle.loadEntryError.emit({\n getRemoteEntry: wrappedGetRemoteEntry,\n origin,\n remoteInfo: remoteInfo,\n remoteEntryExports,\n globalLoading,\n uniqueKey,\n });\n\n if (RemoteEntryExports) {\n return RemoteEntryExports;\n }\n }\n throw err;\n });\n }\n\n return globalLoading[uniqueKey];\n}\n\nexport function getRemoteInfo(remote: Remote): RemoteInfo {\n return {\n ...remote,\n entry: 'entry' in remote ? remote.entry : '',\n type: remote.type || DEFAULT_REMOTE_TYPE,\n entryGlobalName: remote.entryGlobalName || remote.name,\n shareScope: remote.shareScope || DEFAULT_SCOPE,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"load.js","names":[],"sources":["../../src/utils/load.ts"],"sourcesContent":["import {\n loadScript,\n loadScriptNode,\n composeKeyWithSeparator,\n isBrowserEnvValue,\n} from '@module-federation/sdk';\nimport { DEFAULT_REMOTE_TYPE, DEFAULT_SCOPE } from '../constant';\nimport { ModuleFederation } from '../core';\nimport { globalLoading, getRemoteEntryExports } from '../global';\nimport { Remote, RemoteEntryExports, RemoteInfo } from '../type';\nimport { assert, error } from './logger';\nimport {\n RUNTIME_001,\n RUNTIME_008,\n runtimeDescMap,\n} from '@module-federation/error-codes';\n\n// Declare the ENV_TARGET constant that will be defined by DefinePlugin\ndeclare const ENV_TARGET: 'web' | 'node';\nconst importCallback = '.then(callbacks[0]).catch(callbacks[1])';\n\nasync function loadEsmEntry({\n entry,\n remoteEntryExports,\n}: {\n entry: string;\n remoteEntryExports: RemoteEntryExports | undefined;\n}): Promise<RemoteEntryExports> {\n return new Promise<RemoteEntryExports>((resolve, reject) => {\n try {\n if (!remoteEntryExports) {\n if (typeof FEDERATION_ALLOW_NEW_FUNCTION !== 'undefined') {\n new Function('callbacks', `import(\"${entry}\")${importCallback}`)([\n resolve,\n reject,\n ]);\n } else {\n import(/* webpackIgnore: true */ /* @vite-ignore */ entry)\n .then(resolve)\n .catch(reject);\n }\n } else {\n resolve(remoteEntryExports);\n }\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n error(`Failed to load ESM entry from \"${entry}\". ${msg}`);\n }\n });\n}\n\nasync function loadSystemJsEntry({\n entry,\n remoteEntryExports,\n}: {\n entry: string;\n remoteEntryExports: RemoteEntryExports | undefined;\n}): Promise<RemoteEntryExports> {\n return new Promise<RemoteEntryExports>((resolve, reject) => {\n try {\n if (!remoteEntryExports) {\n //@ts-ignore\n if (typeof __system_context__ === 'undefined') {\n //@ts-ignore\n System.import(entry).then(resolve).catch(reject);\n } else {\n new Function(\n 'callbacks',\n `System.import(\"${entry}\")${importCallback}`,\n )([resolve, reject]);\n }\n } else {\n resolve(remoteEntryExports);\n }\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n error(`Failed to load SystemJS entry from \"${entry}\". ${msg}`);\n }\n });\n}\n\nfunction handleRemoteEntryLoaded(\n name: string,\n globalName: string,\n entry: string,\n): RemoteEntryExports {\n const { remoteEntryKey, entryExports } = getRemoteEntryExports(\n name,\n globalName,\n );\n\n if (!entryExports) {\n error(RUNTIME_001, runtimeDescMap, {\n remoteName: name,\n remoteEntryUrl: entry,\n remoteEntryKey,\n });\n }\n\n return entryExports;\n}\n\nasync function loadEntryScript({\n name,\n globalName,\n entry,\n remoteInfo,\n loaderHook,\n getEntryUrl,\n}: {\n name: string;\n globalName: string;\n entry: string;\n remoteInfo: RemoteInfo;\n loaderHook: ModuleFederation['loaderHook'];\n getEntryUrl?: (url: string) => string;\n}): Promise<RemoteEntryExports> {\n const { entryExports: remoteEntryExports } = getRemoteEntryExports(\n name,\n globalName,\n );\n\n if (remoteEntryExports) {\n return remoteEntryExports;\n }\n\n // if getEntryUrl is passed, use the getEntryUrl to get the entry url\n const url = getEntryUrl ? getEntryUrl(entry) : entry;\n return loadScript(url, {\n attrs: {},\n createScriptHook: (url, attrs) => {\n const res = loaderHook.lifecycle.createScript.emit({\n url,\n attrs,\n remoteInfo,\n });\n\n if (!res) return;\n\n if (res instanceof HTMLScriptElement) {\n return res;\n }\n\n if ('script' in res || 'timeout' in res) {\n return res;\n }\n\n return;\n },\n }).then(\n () => {\n // loadScript resolved: script was fetched, executed without throwing, and\n // did not trigger a ScriptExecutionError listener. Now verify the global was registered.\n return handleRemoteEntryLoaded(name, globalName, entry);\n },\n (loadError: unknown) => {\n // loadScript rejected — one of three causes, all with descriptive messages:\n // ScriptNetworkError — URL unreachable, 404, CORS, etc.\n // ScriptExecutionError — script fetched OK but IIFE threw during execution\n // timeout — script took too long to load\n // Errors thrown inside handleRemoteEntryLoaded above are NOT caught here.\n const originalMsg =\n loadError instanceof Error ? loadError.message : String(loadError);\n error(\n RUNTIME_008,\n runtimeDescMap,\n {\n remoteName: name,\n resourceUrl: url,\n },\n originalMsg,\n );\n },\n );\n}\nasync function loadEntryDom({\n remoteInfo,\n remoteEntryExports,\n loaderHook,\n getEntryUrl,\n}: {\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports;\n loaderHook: ModuleFederation['loaderHook'];\n getEntryUrl?: (url: string) => string;\n}) {\n const { entry, entryGlobalName: globalName, name, type } = remoteInfo;\n switch (type) {\n case 'esm':\n case 'module':\n return loadEsmEntry({ entry, remoteEntryExports });\n case 'system':\n return loadSystemJsEntry({ entry, remoteEntryExports });\n default:\n return loadEntryScript({\n entry,\n globalName,\n name,\n remoteInfo,\n loaderHook,\n getEntryUrl,\n });\n }\n}\n\nasync function loadEntryNode({\n remoteInfo,\n loaderHook,\n}: {\n remoteInfo: RemoteInfo;\n loaderHook: ModuleFederation['loaderHook'];\n}) {\n const { entry, entryGlobalName: globalName, name, type } = remoteInfo;\n const { entryExports: remoteEntryExports } = getRemoteEntryExports(\n name,\n globalName,\n );\n\n if (remoteEntryExports) {\n return remoteEntryExports;\n }\n\n return loadScriptNode(entry, {\n attrs: { name, globalName, type },\n loaderHook: {\n createScriptHook: (url: string, attrs: Record<string, any> = {}) => {\n const res = loaderHook.lifecycle.createScript.emit({\n url,\n attrs,\n remoteInfo,\n });\n\n if (!res) return;\n\n if ('url' in res) {\n return res;\n }\n\n return;\n },\n },\n })\n .then(() => {\n return handleRemoteEntryLoaded(name, globalName, entry);\n })\n .catch((e) => {\n const msg = e instanceof Error ? e.message : String(e);\n error(\n `Failed to load Node.js entry for remote \"${name}\" from \"${entry}\". ${msg}`,\n );\n });\n}\n\nexport function getRemoteEntryUniqueKey(remoteInfo: RemoteInfo): string {\n const { entry, name } = remoteInfo;\n return composeKeyWithSeparator(name, entry);\n}\n\nexport async function getRemoteEntry(params: {\n origin: ModuleFederation;\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports | undefined;\n getEntryUrl?: (url: string) => string;\n _inErrorHandling?: boolean; // Add flag to prevent recursion\n}): Promise<RemoteEntryExports | false | void> {\n const {\n origin,\n remoteEntryExports,\n remoteInfo,\n getEntryUrl,\n _inErrorHandling = false,\n } = params;\n const uniqueKey = getRemoteEntryUniqueKey(remoteInfo);\n if (remoteEntryExports) {\n return remoteEntryExports;\n }\n\n if (!globalLoading[uniqueKey]) {\n const loadEntryHook = origin.remoteHandler.hooks.lifecycle.loadEntry;\n const loaderHook = origin.loaderHook;\n\n globalLoading[uniqueKey] = loadEntryHook\n .emit({\n loaderHook,\n remoteInfo,\n remoteEntryExports,\n })\n .then((res) => {\n if (res) {\n return res;\n }\n // Use ENV_TARGET if defined, otherwise fallback to isBrowserEnvValue\n const isWebEnvironment =\n typeof ENV_TARGET !== 'undefined'\n ? ENV_TARGET === 'web'\n : isBrowserEnvValue;\n\n return isWebEnvironment\n ? loadEntryDom({\n remoteInfo,\n remoteEntryExports,\n loaderHook,\n getEntryUrl,\n })\n : loadEntryNode({ remoteInfo, loaderHook });\n })\n .catch(async (err) => {\n const uniqueKey = getRemoteEntryUniqueKey(remoteInfo);\n // ScriptExecutionError means the script downloaded fine but its IIFE\n // threw at runtime — retrying would reproduce the same error, so exclude it.\n const isScriptExecutionError =\n err instanceof Error && err.message.includes('ScriptExecutionError');\n const isScriptLoadError =\n err instanceof Error &&\n err.message.includes(RUNTIME_008) &&\n !isScriptExecutionError;\n\n if (isScriptLoadError && !_inErrorHandling) {\n const wrappedGetRemoteEntry = (\n params: Parameters<typeof getRemoteEntry>[0],\n ) => {\n return getRemoteEntry({ ...params, _inErrorHandling: true });\n };\n\n const RemoteEntryExports =\n await origin.loaderHook.lifecycle.loadEntryError.emit({\n getRemoteEntry: wrappedGetRemoteEntry,\n origin,\n remoteInfo: remoteInfo,\n remoteEntryExports,\n globalLoading,\n uniqueKey,\n });\n\n if (RemoteEntryExports) {\n return RemoteEntryExports;\n }\n }\n throw err;\n });\n }\n\n return globalLoading[uniqueKey];\n}\n\nexport function getRemoteInfo(remote: Remote): RemoteInfo {\n return {\n ...remote,\n entry: 'entry' in remote ? remote.entry : '',\n type: remote.type || DEFAULT_REMOTE_TYPE,\n entryGlobalName: remote.entryGlobalName || remote.name,\n shareScope: remote.shareScope || DEFAULT_SCOPE,\n };\n}\n"],"mappings":"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"}
@@ -9,7 +9,6 @@ function defaultPreloadArgs(preloadConfig) {
9
9
  resourceCategory: "sync",
10
10
  share: true,
11
11
  depsRemote: true,
12
- prefetchInterface: false,
13
12
  ...preloadConfig
14
13
  };
15
14
  }
@@ -64,7 +63,8 @@ function preloadAssets(remoteInfo, host, assets, useLinkPreload = true) {
64
63
  createLinkHook: (url, attrs) => {
65
64
  const res = host.loaderHook.lifecycle.createLink.emit({
66
65
  url,
67
- attrs
66
+ attrs,
67
+ remoteInfo
68
68
  });
69
69
  if (res instanceof HTMLLinkElement) return res;
70
70
  }
@@ -84,7 +84,8 @@ function preloadAssets(remoteInfo, host, assets, useLinkPreload = true) {
84
84
  createLinkHook: (url, attrs) => {
85
85
  const res = host.loaderHook.lifecycle.createLink.emit({
86
86
  url,
87
- attrs
87
+ attrs,
88
+ remoteInfo
88
89
  });
89
90
  if (res instanceof HTMLLinkElement) return res;
90
91
  },
@@ -106,7 +107,8 @@ function preloadAssets(remoteInfo, host, assets, useLinkPreload = true) {
106
107
  createLinkHook: (url, attrs) => {
107
108
  const res = host.loaderHook.lifecycle.createLink.emit({
108
109
  url,
109
- attrs
110
+ attrs,
111
+ remoteInfo
110
112
  });
111
113
  if (res instanceof HTMLLinkElement) return res;
112
114
  }
@@ -126,7 +128,8 @@ function preloadAssets(remoteInfo, host, assets, useLinkPreload = true) {
126
128
  createScriptHook: (url, attrs) => {
127
129
  const res = host.loaderHook.lifecycle.createScript.emit({
128
130
  url,
129
- attrs
131
+ attrs,
132
+ remoteInfo
130
133
  });
131
134
  if (res instanceof HTMLScriptElement) return res;
132
135
  },
@@ -1 +1 @@
1
- {"version":3,"file":"preload.cjs","names":["matchRemote"],"sources":["../../src/utils/preload.ts"],"sourcesContent":["import { createLink, createScript, safeToString } from '@module-federation/sdk';\nimport {\n PreloadAssets,\n PreloadConfig,\n PreloadOptions,\n PreloadRemoteArgs,\n Remote,\n RemoteInfo,\n depsPreloadArg,\n} from '../type';\nimport { matchRemote } from './manifest';\nimport { assert } from './logger';\nimport { ModuleFederation } from '../core';\nimport { getRemoteEntry } from './load';\n\nexport function defaultPreloadArgs(\n preloadConfig: PreloadRemoteArgs | depsPreloadArg,\n): PreloadConfig {\n return {\n resourceCategory: 'sync',\n share: true,\n depsRemote: true,\n prefetchInterface: false,\n ...preloadConfig,\n } as PreloadConfig;\n}\n\nexport function formatPreloadArgs(\n remotes: Array<Remote>,\n preloadArgs: Array<PreloadRemoteArgs>,\n): PreloadOptions {\n return preloadArgs.map((args) => {\n const remoteInfo = matchRemote(remotes, args.nameOrAlias);\n assert(\n remoteInfo,\n `Unable to preload ${args.nameOrAlias} as it is not included in ${\n !remoteInfo &&\n safeToString({\n remoteInfo,\n remotes,\n })\n }`,\n );\n return {\n remote: remoteInfo,\n preloadConfig: defaultPreloadArgs(args),\n };\n });\n}\n\nexport function normalizePreloadExposes(exposes?: string[]): string[] {\n if (!exposes) {\n return [];\n }\n\n return exposes.map((expose) => {\n if (expose === '.') {\n return expose;\n }\n if (expose.startsWith('./')) {\n return expose.replace('./', '');\n }\n return expose;\n });\n}\n\nexport function preloadAssets(\n remoteInfo: RemoteInfo,\n host: ModuleFederation,\n assets: PreloadAssets,\n // It is used to distinguish preload from load remote parallel loading\n useLinkPreload = true,\n): void {\n const { cssAssets, jsAssetsWithoutEntry, entryAssets } = assets;\n\n if (host.options.inBrowser) {\n entryAssets.forEach((asset) => {\n const { moduleInfo } = asset;\n const module = host.moduleCache.get(remoteInfo.name);\n if (module) {\n getRemoteEntry({\n origin: host,\n remoteInfo: moduleInfo,\n remoteEntryExports: module.remoteEntryExports,\n });\n } else {\n getRemoteEntry({\n origin: host,\n remoteInfo: moduleInfo,\n remoteEntryExports: undefined,\n });\n }\n });\n\n if (useLinkPreload) {\n const defaultAttrs = {\n rel: 'preload',\n as: 'style',\n };\n cssAssets.forEach((cssUrl) => {\n const { link: cssEl, needAttach } = createLink({\n url: cssUrl,\n cb: () => {\n // noop\n },\n attrs: defaultAttrs,\n createLinkHook: (url, attrs) => {\n const res = host.loaderHook.lifecycle.createLink.emit({\n url,\n attrs,\n });\n if (res instanceof HTMLLinkElement) {\n return res;\n }\n return;\n },\n });\n\n needAttach && document.head.appendChild(cssEl);\n });\n } else {\n const defaultAttrs = {\n rel: 'stylesheet',\n type: 'text/css',\n };\n cssAssets.forEach((cssUrl) => {\n const { link: cssEl, needAttach } = createLink({\n url: cssUrl,\n cb: () => {\n // noop\n },\n attrs: defaultAttrs,\n createLinkHook: (url, attrs) => {\n const res = host.loaderHook.lifecycle.createLink.emit({\n url,\n attrs,\n });\n if (res instanceof HTMLLinkElement) {\n return res;\n }\n return;\n },\n needDeleteLink: false,\n });\n\n needAttach && document.head.appendChild(cssEl);\n });\n }\n\n if (useLinkPreload) {\n const defaultAttrs = {\n rel: 'preload',\n as: 'script',\n };\n jsAssetsWithoutEntry.forEach((jsUrl) => {\n const { link: linkEl, needAttach } = createLink({\n url: jsUrl,\n cb: () => {\n // noop\n },\n attrs: defaultAttrs,\n createLinkHook: (url: string, attrs) => {\n const res = host.loaderHook.lifecycle.createLink.emit({\n url,\n attrs,\n });\n if (res instanceof HTMLLinkElement) {\n return res;\n }\n return;\n },\n });\n needAttach && document.head.appendChild(linkEl);\n });\n } else {\n const defaultAttrs = {\n fetchpriority: 'high',\n type: remoteInfo?.type === 'module' ? 'module' : 'text/javascript',\n };\n jsAssetsWithoutEntry.forEach((jsUrl) => {\n const { script: scriptEl, needAttach } = createScript({\n url: jsUrl,\n cb: () => {\n // noop\n },\n attrs: defaultAttrs,\n createScriptHook: (url: string, attrs: any) => {\n const res = host.loaderHook.lifecycle.createScript.emit({\n url,\n attrs,\n });\n if (res instanceof HTMLScriptElement) {\n return res;\n }\n return;\n },\n needDeleteScript: true,\n });\n needAttach && document.head.appendChild(scriptEl);\n });\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"preload.cjs","names":["matchRemote"],"sources":["../../src/utils/preload.ts"],"sourcesContent":["import { createLink, createScript, safeToString } from '@module-federation/sdk';\nimport {\n PreloadAssets,\n PreloadConfig,\n PreloadOptions,\n PreloadRemoteArgs,\n Remote,\n RemoteInfo,\n depsPreloadArg,\n} from '../type';\nimport { matchRemote } from './manifest';\nimport { assert } from './logger';\nimport { ModuleFederation } from '../core';\nimport { getRemoteEntry } from './load';\n\nexport function defaultPreloadArgs(\n preloadConfig: PreloadRemoteArgs | depsPreloadArg,\n): PreloadConfig {\n return {\n resourceCategory: 'sync',\n share: true,\n depsRemote: true,\n ...preloadConfig,\n } as PreloadConfig;\n}\n\nexport function formatPreloadArgs(\n remotes: Array<Remote>,\n preloadArgs: Array<PreloadRemoteArgs>,\n): PreloadOptions {\n return preloadArgs.map((args) => {\n const remoteInfo = matchRemote(remotes, args.nameOrAlias);\n assert(\n remoteInfo,\n `Unable to preload ${args.nameOrAlias} as it is not included in ${\n !remoteInfo &&\n safeToString({\n remoteInfo,\n remotes,\n })\n }`,\n );\n return {\n remote: remoteInfo,\n preloadConfig: defaultPreloadArgs(args),\n };\n });\n}\n\nexport function normalizePreloadExposes(exposes?: string[]): string[] {\n if (!exposes) {\n return [];\n }\n\n return exposes.map((expose) => {\n if (expose === '.') {\n return expose;\n }\n if (expose.startsWith('./')) {\n return expose.replace('./', '');\n }\n return expose;\n });\n}\n\nexport function preloadAssets(\n remoteInfo: RemoteInfo,\n host: ModuleFederation,\n assets: PreloadAssets,\n // It is used to distinguish preload from load remote parallel loading\n useLinkPreload = true,\n): void {\n const { cssAssets, jsAssetsWithoutEntry, entryAssets } = assets;\n\n if (host.options.inBrowser) {\n entryAssets.forEach((asset) => {\n const { moduleInfo } = asset;\n const module = host.moduleCache.get(remoteInfo.name);\n if (module) {\n getRemoteEntry({\n origin: host,\n remoteInfo: moduleInfo,\n remoteEntryExports: module.remoteEntryExports,\n });\n } else {\n getRemoteEntry({\n origin: host,\n remoteInfo: moduleInfo,\n remoteEntryExports: undefined,\n });\n }\n });\n\n if (useLinkPreload) {\n const defaultAttrs = {\n rel: 'preload',\n as: 'style',\n };\n cssAssets.forEach((cssUrl) => {\n const { link: cssEl, needAttach } = createLink({\n url: cssUrl,\n cb: () => {\n // noop\n },\n attrs: defaultAttrs,\n createLinkHook: (url, attrs) => {\n const res = host.loaderHook.lifecycle.createLink.emit({\n url,\n attrs,\n remoteInfo,\n });\n if (res instanceof HTMLLinkElement) {\n return res;\n }\n return;\n },\n });\n\n needAttach && document.head.appendChild(cssEl);\n });\n } else {\n const defaultAttrs = {\n rel: 'stylesheet',\n type: 'text/css',\n };\n cssAssets.forEach((cssUrl) => {\n const { link: cssEl, needAttach } = createLink({\n url: cssUrl,\n cb: () => {\n // noop\n },\n attrs: defaultAttrs,\n createLinkHook: (url, attrs) => {\n const res = host.loaderHook.lifecycle.createLink.emit({\n url,\n attrs,\n remoteInfo,\n });\n if (res instanceof HTMLLinkElement) {\n return res;\n }\n return;\n },\n needDeleteLink: false,\n });\n\n needAttach && document.head.appendChild(cssEl);\n });\n }\n\n if (useLinkPreload) {\n const defaultAttrs = {\n rel: 'preload',\n as: 'script',\n };\n jsAssetsWithoutEntry.forEach((jsUrl) => {\n const { link: linkEl, needAttach } = createLink({\n url: jsUrl,\n cb: () => {\n // noop\n },\n attrs: defaultAttrs,\n createLinkHook: (url: string, attrs) => {\n const res = host.loaderHook.lifecycle.createLink.emit({\n url,\n attrs,\n remoteInfo,\n });\n if (res instanceof HTMLLinkElement) {\n return res;\n }\n return;\n },\n });\n needAttach && document.head.appendChild(linkEl);\n });\n } else {\n const defaultAttrs = {\n fetchpriority: 'high',\n type: remoteInfo?.type === 'module' ? 'module' : 'text/javascript',\n };\n jsAssetsWithoutEntry.forEach((jsUrl) => {\n const { script: scriptEl, needAttach } = createScript({\n url: jsUrl,\n cb: () => {\n // noop\n },\n attrs: defaultAttrs,\n createScriptHook: (url: string, attrs: any) => {\n const res = host.loaderHook.lifecycle.createScript.emit({\n url,\n attrs,\n remoteInfo,\n });\n if (res instanceof HTMLScriptElement) {\n return res;\n }\n return;\n },\n needDeleteScript: true,\n });\n needAttach && document.head.appendChild(scriptEl);\n });\n }\n }\n}\n"],"mappings":"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"}
@@ -9,7 +9,6 @@ function defaultPreloadArgs(preloadConfig) {
9
9
  resourceCategory: "sync",
10
10
  share: true,
11
11
  depsRemote: true,
12
- prefetchInterface: false,
13
12
  ...preloadConfig
14
13
  };
15
14
  }
@@ -64,7 +63,8 @@ function preloadAssets(remoteInfo, host, assets, useLinkPreload = true) {
64
63
  createLinkHook: (url, attrs) => {
65
64
  const res = host.loaderHook.lifecycle.createLink.emit({
66
65
  url,
67
- attrs
66
+ attrs,
67
+ remoteInfo
68
68
  });
69
69
  if (res instanceof HTMLLinkElement) return res;
70
70
  }
@@ -84,7 +84,8 @@ function preloadAssets(remoteInfo, host, assets, useLinkPreload = true) {
84
84
  createLinkHook: (url, attrs) => {
85
85
  const res = host.loaderHook.lifecycle.createLink.emit({
86
86
  url,
87
- attrs
87
+ attrs,
88
+ remoteInfo
88
89
  });
89
90
  if (res instanceof HTMLLinkElement) return res;
90
91
  },
@@ -106,7 +107,8 @@ function preloadAssets(remoteInfo, host, assets, useLinkPreload = true) {
106
107
  createLinkHook: (url, attrs) => {
107
108
  const res = host.loaderHook.lifecycle.createLink.emit({
108
109
  url,
109
- attrs
110
+ attrs,
111
+ remoteInfo
110
112
  });
111
113
  if (res instanceof HTMLLinkElement) return res;
112
114
  }
@@ -126,7 +128,8 @@ function preloadAssets(remoteInfo, host, assets, useLinkPreload = true) {
126
128
  createScriptHook: (url, attrs) => {
127
129
  const res = host.loaderHook.lifecycle.createScript.emit({
128
130
  url,
129
- attrs
131
+ attrs,
132
+ remoteInfo
130
133
  });
131
134
  if (res instanceof HTMLScriptElement) return res;
132
135
  },
@@ -1 +1 @@
1
- {"version":3,"file":"preload.js","names":[],"sources":["../../src/utils/preload.ts"],"sourcesContent":["import { createLink, createScript, safeToString } from '@module-federation/sdk';\nimport {\n PreloadAssets,\n PreloadConfig,\n PreloadOptions,\n PreloadRemoteArgs,\n Remote,\n RemoteInfo,\n depsPreloadArg,\n} from '../type';\nimport { matchRemote } from './manifest';\nimport { assert } from './logger';\nimport { ModuleFederation } from '../core';\nimport { getRemoteEntry } from './load';\n\nexport function defaultPreloadArgs(\n preloadConfig: PreloadRemoteArgs | depsPreloadArg,\n): PreloadConfig {\n return {\n resourceCategory: 'sync',\n share: true,\n depsRemote: true,\n prefetchInterface: false,\n ...preloadConfig,\n } as PreloadConfig;\n}\n\nexport function formatPreloadArgs(\n remotes: Array<Remote>,\n preloadArgs: Array<PreloadRemoteArgs>,\n): PreloadOptions {\n return preloadArgs.map((args) => {\n const remoteInfo = matchRemote(remotes, args.nameOrAlias);\n assert(\n remoteInfo,\n `Unable to preload ${args.nameOrAlias} as it is not included in ${\n !remoteInfo &&\n safeToString({\n remoteInfo,\n remotes,\n })\n }`,\n );\n return {\n remote: remoteInfo,\n preloadConfig: defaultPreloadArgs(args),\n };\n });\n}\n\nexport function normalizePreloadExposes(exposes?: string[]): string[] {\n if (!exposes) {\n return [];\n }\n\n return exposes.map((expose) => {\n if (expose === '.') {\n return expose;\n }\n if (expose.startsWith('./')) {\n return expose.replace('./', '');\n }\n return expose;\n });\n}\n\nexport function preloadAssets(\n remoteInfo: RemoteInfo,\n host: ModuleFederation,\n assets: PreloadAssets,\n // It is used to distinguish preload from load remote parallel loading\n useLinkPreload = true,\n): void {\n const { cssAssets, jsAssetsWithoutEntry, entryAssets } = assets;\n\n if (host.options.inBrowser) {\n entryAssets.forEach((asset) => {\n const { moduleInfo } = asset;\n const module = host.moduleCache.get(remoteInfo.name);\n if (module) {\n getRemoteEntry({\n origin: host,\n remoteInfo: moduleInfo,\n remoteEntryExports: module.remoteEntryExports,\n });\n } else {\n getRemoteEntry({\n origin: host,\n remoteInfo: moduleInfo,\n remoteEntryExports: undefined,\n });\n }\n });\n\n if (useLinkPreload) {\n const defaultAttrs = {\n rel: 'preload',\n as: 'style',\n };\n cssAssets.forEach((cssUrl) => {\n const { link: cssEl, needAttach } = createLink({\n url: cssUrl,\n cb: () => {\n // noop\n },\n attrs: defaultAttrs,\n createLinkHook: (url, attrs) => {\n const res = host.loaderHook.lifecycle.createLink.emit({\n url,\n attrs,\n });\n if (res instanceof HTMLLinkElement) {\n return res;\n }\n return;\n },\n });\n\n needAttach && document.head.appendChild(cssEl);\n });\n } else {\n const defaultAttrs = {\n rel: 'stylesheet',\n type: 'text/css',\n };\n cssAssets.forEach((cssUrl) => {\n const { link: cssEl, needAttach } = createLink({\n url: cssUrl,\n cb: () => {\n // noop\n },\n attrs: defaultAttrs,\n createLinkHook: (url, attrs) => {\n const res = host.loaderHook.lifecycle.createLink.emit({\n url,\n attrs,\n });\n if (res instanceof HTMLLinkElement) {\n return res;\n }\n return;\n },\n needDeleteLink: false,\n });\n\n needAttach && document.head.appendChild(cssEl);\n });\n }\n\n if (useLinkPreload) {\n const defaultAttrs = {\n rel: 'preload',\n as: 'script',\n };\n jsAssetsWithoutEntry.forEach((jsUrl) => {\n const { link: linkEl, needAttach } = createLink({\n url: jsUrl,\n cb: () => {\n // noop\n },\n attrs: defaultAttrs,\n createLinkHook: (url: string, attrs) => {\n const res = host.loaderHook.lifecycle.createLink.emit({\n url,\n attrs,\n });\n if (res instanceof HTMLLinkElement) {\n return res;\n }\n return;\n },\n });\n needAttach && document.head.appendChild(linkEl);\n });\n } else {\n const defaultAttrs = {\n fetchpriority: 'high',\n type: remoteInfo?.type === 'module' ? 'module' : 'text/javascript',\n };\n jsAssetsWithoutEntry.forEach((jsUrl) => {\n const { script: scriptEl, needAttach } = createScript({\n url: jsUrl,\n cb: () => {\n // noop\n },\n attrs: defaultAttrs,\n createScriptHook: (url: string, attrs: any) => {\n const res = host.loaderHook.lifecycle.createScript.emit({\n url,\n attrs,\n });\n if (res instanceof HTMLScriptElement) {\n return res;\n }\n return;\n },\n needDeleteScript: true,\n });\n needAttach && document.head.appendChild(scriptEl);\n });\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"preload.js","names":[],"sources":["../../src/utils/preload.ts"],"sourcesContent":["import { createLink, createScript, safeToString } from '@module-federation/sdk';\nimport {\n PreloadAssets,\n PreloadConfig,\n PreloadOptions,\n PreloadRemoteArgs,\n Remote,\n RemoteInfo,\n depsPreloadArg,\n} from '../type';\nimport { matchRemote } from './manifest';\nimport { assert } from './logger';\nimport { ModuleFederation } from '../core';\nimport { getRemoteEntry } from './load';\n\nexport function defaultPreloadArgs(\n preloadConfig: PreloadRemoteArgs | depsPreloadArg,\n): PreloadConfig {\n return {\n resourceCategory: 'sync',\n share: true,\n depsRemote: true,\n ...preloadConfig,\n } as PreloadConfig;\n}\n\nexport function formatPreloadArgs(\n remotes: Array<Remote>,\n preloadArgs: Array<PreloadRemoteArgs>,\n): PreloadOptions {\n return preloadArgs.map((args) => {\n const remoteInfo = matchRemote(remotes, args.nameOrAlias);\n assert(\n remoteInfo,\n `Unable to preload ${args.nameOrAlias} as it is not included in ${\n !remoteInfo &&\n safeToString({\n remoteInfo,\n remotes,\n })\n }`,\n );\n return {\n remote: remoteInfo,\n preloadConfig: defaultPreloadArgs(args),\n };\n });\n}\n\nexport function normalizePreloadExposes(exposes?: string[]): string[] {\n if (!exposes) {\n return [];\n }\n\n return exposes.map((expose) => {\n if (expose === '.') {\n return expose;\n }\n if (expose.startsWith('./')) {\n return expose.replace('./', '');\n }\n return expose;\n });\n}\n\nexport function preloadAssets(\n remoteInfo: RemoteInfo,\n host: ModuleFederation,\n assets: PreloadAssets,\n // It is used to distinguish preload from load remote parallel loading\n useLinkPreload = true,\n): void {\n const { cssAssets, jsAssetsWithoutEntry, entryAssets } = assets;\n\n if (host.options.inBrowser) {\n entryAssets.forEach((asset) => {\n const { moduleInfo } = asset;\n const module = host.moduleCache.get(remoteInfo.name);\n if (module) {\n getRemoteEntry({\n origin: host,\n remoteInfo: moduleInfo,\n remoteEntryExports: module.remoteEntryExports,\n });\n } else {\n getRemoteEntry({\n origin: host,\n remoteInfo: moduleInfo,\n remoteEntryExports: undefined,\n });\n }\n });\n\n if (useLinkPreload) {\n const defaultAttrs = {\n rel: 'preload',\n as: 'style',\n };\n cssAssets.forEach((cssUrl) => {\n const { link: cssEl, needAttach } = createLink({\n url: cssUrl,\n cb: () => {\n // noop\n },\n attrs: defaultAttrs,\n createLinkHook: (url, attrs) => {\n const res = host.loaderHook.lifecycle.createLink.emit({\n url,\n attrs,\n remoteInfo,\n });\n if (res instanceof HTMLLinkElement) {\n return res;\n }\n return;\n },\n });\n\n needAttach && document.head.appendChild(cssEl);\n });\n } else {\n const defaultAttrs = {\n rel: 'stylesheet',\n type: 'text/css',\n };\n cssAssets.forEach((cssUrl) => {\n const { link: cssEl, needAttach } = createLink({\n url: cssUrl,\n cb: () => {\n // noop\n },\n attrs: defaultAttrs,\n createLinkHook: (url, attrs) => {\n const res = host.loaderHook.lifecycle.createLink.emit({\n url,\n attrs,\n remoteInfo,\n });\n if (res instanceof HTMLLinkElement) {\n return res;\n }\n return;\n },\n needDeleteLink: false,\n });\n\n needAttach && document.head.appendChild(cssEl);\n });\n }\n\n if (useLinkPreload) {\n const defaultAttrs = {\n rel: 'preload',\n as: 'script',\n };\n jsAssetsWithoutEntry.forEach((jsUrl) => {\n const { link: linkEl, needAttach } = createLink({\n url: jsUrl,\n cb: () => {\n // noop\n },\n attrs: defaultAttrs,\n createLinkHook: (url: string, attrs) => {\n const res = host.loaderHook.lifecycle.createLink.emit({\n url,\n attrs,\n remoteInfo,\n });\n if (res instanceof HTMLLinkElement) {\n return res;\n }\n return;\n },\n });\n needAttach && document.head.appendChild(linkEl);\n });\n } else {\n const defaultAttrs = {\n fetchpriority: 'high',\n type: remoteInfo?.type === 'module' ? 'module' : 'text/javascript',\n };\n jsAssetsWithoutEntry.forEach((jsUrl) => {\n const { script: scriptEl, needAttach } = createScript({\n url: jsUrl,\n cb: () => {\n // noop\n },\n attrs: defaultAttrs,\n createScriptHook: (url: string, attrs: any) => {\n const res = host.loaderHook.lifecycle.createScript.emit({\n url,\n attrs,\n remoteInfo,\n });\n if (res instanceof HTMLScriptElement) {\n return res;\n }\n return;\n },\n needDeleteScript: true,\n });\n needAttach && document.head.appendChild(scriptEl);\n });\n }\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@module-federation/runtime-core",
3
- "version": "2.3.2",
3
+ "version": "2.4.0",
4
4
  "type": "module",
5
5
  "author": "zhouxiao <codingzx@gmail.com>",
6
6
  "main": "./dist/index.cjs",
@@ -52,8 +52,8 @@
52
52
  }
53
53
  },
54
54
  "dependencies": {
55
- "@module-federation/sdk": "2.3.2",
56
- "@module-federation/error-codes": "2.3.2"
55
+ "@module-federation/sdk": "2.4.0",
56
+ "@module-federation/error-codes": "2.4.0"
57
57
  },
58
58
  "scripts": {
59
59
  "build": "tsdown --config tsdown.config.ts",