@module-federation/runtime 0.0.0-next-20240814104132 → 0.0.0-next-20240815093707

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/index.cjs.js CHANGED
@@ -142,29 +142,80 @@ async function loadEntryScript({ name, globalName, entry, createScriptHook }) {
142
142
  if (remoteEntryExports) {
143
143
  return remoteEntryExports;
144
144
  }
145
- if (typeof document === 'undefined') {
146
- return sdk.loadScriptNode(entry, {
147
- attrs: {
148
- name,
149
- globalName
150
- },
151
- createScriptHook
152
- }).then(()=>{
153
- const { remoteEntryKey, entryExports } = share.getRemoteEntryExports(name, globalName);
154
- share.assert(entryExports, `
155
- Unable to use the ${name}'s '${entry}' URL with ${remoteEntryKey}'s globalName to get remoteEntry exports.
156
- Possible reasons could be:\n
157
- 1. '${entry}' is not the correct URL, or the remoteEntry resource or name is incorrect.\n
158
- 2. ${remoteEntryKey} cannot be used to get remoteEntry exports in the window object.
159
- `);
160
- return entryExports;
161
- }).catch((e)=>{
162
- throw e;
163
- });
164
- }
165
145
  return sdk.loadScript(entry, {
166
146
  attrs: {},
167
- createScriptHook
147
+ createScriptHook: (url, attrs)=>{
148
+ const res = createScriptHook.emit({
149
+ url,
150
+ attrs
151
+ });
152
+ if (!res) return;
153
+ if (res instanceof HTMLScriptElement) {
154
+ return res;
155
+ }
156
+ if ('script' in res || 'timeout' in res) {
157
+ return res;
158
+ }
159
+ return;
160
+ }
161
+ }).then(()=>{
162
+ const { remoteEntryKey, entryExports } = share.getRemoteEntryExports(name, globalName);
163
+ share.assert(entryExports, `
164
+ Unable to use the ${name}'s '${entry}' URL with ${remoteEntryKey}'s globalName to get remoteEntry exports.
165
+ Possible reasons could be:\n
166
+ 1. '${entry}' is not the correct URL, or the remoteEntry resource or name is incorrect.\n
167
+ 2. ${remoteEntryKey} cannot be used to get remoteEntry exports in the window object.
168
+ `);
169
+ return entryExports;
170
+ }).catch((e)=>{
171
+ throw e;
172
+ });
173
+ }
174
+ async function loadEntryDom({ remoteInfo, remoteEntryExports, createScriptHook }) {
175
+ const { entry, entryGlobalName: globalName, name, type } = remoteInfo;
176
+ switch(type){
177
+ case 'esm':
178
+ case 'module':
179
+ return loadEsmEntry({
180
+ entry,
181
+ remoteEntryExports
182
+ });
183
+ case 'system':
184
+ return loadSystemJsEntry({
185
+ entry,
186
+ remoteEntryExports
187
+ });
188
+ default:
189
+ return loadEntryScript({
190
+ entry,
191
+ globalName,
192
+ name,
193
+ createScriptHook
194
+ });
195
+ }
196
+ }
197
+ async function loadEntryNode({ remoteInfo, createScriptHook }) {
198
+ const { entry, entryGlobalName: globalName, name } = remoteInfo;
199
+ const { entryExports: remoteEntryExports } = share.getRemoteEntryExports(name, globalName);
200
+ if (remoteEntryExports) {
201
+ return remoteEntryExports;
202
+ }
203
+ return sdk.loadScriptNode(entry, {
204
+ attrs: {
205
+ name,
206
+ globalName
207
+ },
208
+ createScriptHook: (url, attrs)=>{
209
+ const res = createScriptHook.emit({
210
+ url,
211
+ attrs
212
+ });
213
+ if (!res) return;
214
+ if ('url' in res) {
215
+ return res;
216
+ }
217
+ return;
218
+ }
168
219
  }).then(()=>{
169
220
  const { remoteEntryKey, entryExports } = share.getRemoteEntryExports(name, globalName);
170
221
  share.assert(entryExports, `
@@ -182,33 +233,33 @@ function getRemoteEntryUniqueKey(remoteInfo) {
182
233
  const { entry, name } = remoteInfo;
183
234
  return sdk.composeKeyWithSeparator(name, entry);
184
235
  }
185
- async function getRemoteEntry({ remoteEntryExports, remoteInfo, createScriptHook }) {
186
- const { entry, name, type, entryGlobalName } = remoteInfo;
236
+ async function getRemoteEntry({ origin, remoteEntryExports, remoteInfo }) {
187
237
  const uniqueKey = getRemoteEntryUniqueKey(remoteInfo);
188
238
  if (remoteEntryExports) {
189
239
  return remoteEntryExports;
190
240
  }
191
241
  if (!share.globalLoading[uniqueKey]) {
192
- if ([
193
- 'esm',
194
- 'module'
195
- ].includes(type)) {
196
- share.globalLoading[uniqueKey] = loadEsmEntry({
197
- entry,
198
- remoteEntryExports
199
- });
200
- } else if (type === 'system') {
201
- share.globalLoading[uniqueKey] = loadSystemJsEntry({
202
- entry,
242
+ const loadEntryHook = origin.remoteHandler.hooks.lifecycle.loadEntry;
243
+ if (loadEntryHook.listeners.size) {
244
+ share.globalLoading[uniqueKey] = loadEntryHook.emit({
245
+ createScriptHook: origin.loaderHook.lifecycle.createScript,
246
+ remoteInfo,
203
247
  remoteEntryExports
204
- });
248
+ }).then((res)=>res || undefined);
205
249
  } else {
206
- share.globalLoading[uniqueKey] = loadEntryScript({
207
- name,
208
- globalName: entryGlobalName,
209
- entry,
210
- createScriptHook
211
- });
250
+ const createScriptHook = origin.loaderHook.lifecycle.createScript;
251
+ if (!sdk.isBrowserEnv()) {
252
+ share.globalLoading[uniqueKey] = loadEntryNode({
253
+ remoteInfo,
254
+ createScriptHook
255
+ });
256
+ } else {
257
+ share.globalLoading[uniqueKey] = loadEntryDom({
258
+ remoteInfo,
259
+ remoteEntryExports,
260
+ createScriptHook
261
+ });
262
+ }
212
263
  }
213
264
  }
214
265
  return share.globalLoading[uniqueKey];
@@ -243,26 +294,9 @@ let Module = class Module {
243
294
  }
244
295
  // Get remoteEntry.js
245
296
  const remoteEntryExports = await getRemoteEntry({
297
+ origin: this.host,
246
298
  remoteInfo: this.remoteInfo,
247
- remoteEntryExports: this.remoteEntryExports,
248
- createScriptHook: (url, attrs)=>{
249
- const res = this.host.loaderHook.lifecycle.createScript.emit({
250
- url,
251
- attrs
252
- });
253
- if (!res) return;
254
- if (typeof document === 'undefined') {
255
- //todo: needs real fix
256
- return res;
257
- }
258
- if (res instanceof HTMLScriptElement) {
259
- return res;
260
- }
261
- if ('script' in res || 'timeout' in res) {
262
- return res;
263
- }
264
- return;
265
- }
299
+ remoteEntryExports: this.remoteEntryExports
266
300
  });
267
301
  share.assert(remoteEntryExports, `remoteEntryExports is undefined \n ${share.safeToString(this.remoteInfo)}`);
268
302
  this.remoteEntryExports = remoteEntryExports;
@@ -598,49 +632,15 @@ useLinkPreload = true) {
598
632
  const module = host.moduleCache.get(remoteInfo.name);
599
633
  if (module) {
600
634
  getRemoteEntry({
635
+ origin: host,
601
636
  remoteInfo: moduleInfo,
602
- remoteEntryExports: module.remoteEntryExports,
603
- createScriptHook: (url, attrs)=>{
604
- const res = host.loaderHook.lifecycle.createScript.emit({
605
- url,
606
- attrs
607
- });
608
- if (!res) return;
609
- if (typeof document === 'undefined') {
610
- //todo: needs real fix
611
- return res;
612
- }
613
- if (res instanceof HTMLScriptElement) {
614
- return res;
615
- }
616
- if ('script' in res || 'timeout' in res) {
617
- return res;
618
- }
619
- return;
620
- }
637
+ remoteEntryExports: module.remoteEntryExports
621
638
  });
622
639
  } else {
623
640
  getRemoteEntry({
641
+ origin: host,
624
642
  remoteInfo: moduleInfo,
625
- remoteEntryExports: undefined,
626
- createScriptHook: (url, attrs)=>{
627
- const res = host.loaderHook.lifecycle.createScript.emit({
628
- url,
629
- attrs
630
- });
631
- if (!res) return;
632
- if (typeof document === 'undefined') {
633
- //todo: needs real fix
634
- return res;
635
- }
636
- if (res instanceof HTMLScriptElement) {
637
- return res;
638
- }
639
- if ('script' in res || 'timeout' in res) {
640
- return res;
641
- }
642
- return;
643
- }
643
+ remoteEntryExports: undefined
644
644
  });
645
645
  }
646
646
  });
@@ -1123,6 +1123,8 @@ class SnapshotHandler {
1123
1123
  remoteSnapshot,
1124
1124
  globalSnapshot
1125
1125
  });
1126
+ let mSnapshot;
1127
+ let gSnapshot;
1126
1128
  // global snapshot includes manifest or module info includes manifest
1127
1129
  if (globalRemoteSnapshot) {
1128
1130
  if (sdk.isManifestProvider(globalRemoteSnapshot)) {
@@ -1134,10 +1136,8 @@ class SnapshotHandler {
1134
1136
  // Therefore, set the snapshot key to the global address of the actual request
1135
1137
  entry: remoteEntry
1136
1138
  }), moduleSnapshot);
1137
- return {
1138
- remoteSnapshot: moduleSnapshot,
1139
- globalSnapshot: globalSnapshotRes
1140
- };
1139
+ mSnapshot = moduleSnapshot;
1140
+ gSnapshot = globalSnapshotRes;
1141
1141
  } else {
1142
1142
  const { remoteSnapshot: remoteSnapshotRes } = await this.hooks.lifecycle.loadRemoteSnapshot.emit({
1143
1143
  options: this.HostInstance.options,
@@ -1145,10 +1145,8 @@ class SnapshotHandler {
1145
1145
  remoteSnapshot: globalRemoteSnapshot,
1146
1146
  from: 'global'
1147
1147
  });
1148
- return {
1149
- remoteSnapshot: remoteSnapshotRes,
1150
- globalSnapshot: globalSnapshotRes
1151
- };
1148
+ mSnapshot = remoteSnapshotRes;
1149
+ gSnapshot = globalSnapshotRes;
1152
1150
  }
1153
1151
  } else {
1154
1152
  if (share.isRemoteInfoWithEntry(moduleInfo)) {
@@ -1162,10 +1160,8 @@ class SnapshotHandler {
1162
1160
  remoteSnapshot: moduleSnapshot,
1163
1161
  from: 'global'
1164
1162
  });
1165
- return {
1166
- remoteSnapshot: remoteSnapshotRes,
1167
- globalSnapshot: globalSnapshotRes
1168
- };
1163
+ mSnapshot = remoteSnapshotRes;
1164
+ gSnapshot = globalSnapshotRes;
1169
1165
  } else {
1170
1166
  share.error(`
1171
1167
  Cannot get remoteSnapshot with the name: '${moduleInfo.name}', version: '${moduleInfo.version}' from __FEDERATION__.moduleInfo. The following reasons may be causing the problem:\n
@@ -1175,6 +1171,10 @@ class SnapshotHandler {
1175
1171
  `);
1176
1172
  }
1177
1173
  }
1174
+ return {
1175
+ remoteSnapshot: mSnapshot,
1176
+ globalSnapshot: gSnapshot
1177
+ };
1178
1178
  }
1179
1179
  getGlobalRemoteInfo(moduleInfo) {
1180
1180
  return getGlobalRemoteInfo(moduleInfo, this.HostInstance);
@@ -1227,7 +1227,8 @@ class SnapshotHandler {
1227
1227
  this.hooks = new PluginSystem({
1228
1228
  beforeLoadRemoteSnapshot: new AsyncHook('beforeLoadRemoteSnapshot'),
1229
1229
  loadSnapshot: new AsyncWaterfallHook('loadGlobalSnapshot'),
1230
- loadRemoteSnapshot: new AsyncWaterfallHook('loadRemoteSnapshot')
1230
+ loadRemoteSnapshot: new AsyncWaterfallHook('loadRemoteSnapshot'),
1231
+ afterLoadSnapshot: new AsyncWaterfallHook('loadRemoteSnapshot')
1231
1232
  });
1232
1233
  this.manifestLoading = share.Global.__FEDERATION__.__MANIFEST_LOADING__;
1233
1234
  this.HostInstance = HostInstance;
@@ -1950,7 +1951,8 @@ class RemoteHandler {
1950
1951
  beforePreloadRemote: new AsyncHook('beforePreloadRemote'),
1951
1952
  generatePreloadAssets: new AsyncHook('generatePreloadAssets'),
1952
1953
  // not used yet
1953
- afterPreloadRemote: new AsyncHook()
1954
+ afterPreloadRemote: new AsyncHook(),
1955
+ loadEntry: new AsyncHook()
1954
1956
  });
1955
1957
  this.host = host;
1956
1958
  this.idToRemoteMap = {};
package/dist/index.esm.js CHANGED
@@ -1,6 +1,6 @@
1
- import { g as getGlobalHostPlugins, a as globalLoading, D as DEFAULT_REMOTE_TYPE, b as DEFAULT_SCOPE, c as getRemoteEntryExports, d as assert, s as safeToString, e as getFMId, i as isObject, f as error, w as warn, h as isPlainObject, j as isRemoteInfoWithEntry, k as isPureRemoteEntry, l as getRemoteEntryInfoFromSnapshot, m as isBrowserEnv, n as getInfoWithoutType, o as getPreloaded, p as setPreloaded, q as getRegisteredShare, r as arrayOptions, t as getGlobalSnapshotInfoByModuleInfo, u as addGlobalSnapshot, v as setGlobalSnapshotInfoByModuleInfo, G as Global, x as getGlobalSnapshot, y as formatShareConfigs, z as getTargetSharedOptions, A as getGlobalShareScope, B as addUniqueItem, C as getBuilderId, E as setGlobalFederationConstructor, F as getGlobalFederationInstance, H as getGlobalFederationConstructor, I as setGlobalFederationInstance } from './share.esm.js';
1
+ import { g as getGlobalHostPlugins, a as globalLoading, D as DEFAULT_REMOTE_TYPE, b as DEFAULT_SCOPE, c as getRemoteEntryExports, d as assert, s as safeToString, e as getFMId, i as isObject, f as error, w as warn, h as isPlainObject, j as isRemoteInfoWithEntry, k as isPureRemoteEntry, l as getRemoteEntryInfoFromSnapshot, m as isBrowserEnv$1, n as getInfoWithoutType, o as getPreloaded, p as setPreloaded, q as getRegisteredShare, r as arrayOptions, t as getGlobalSnapshotInfoByModuleInfo, u as addGlobalSnapshot, v as setGlobalSnapshotInfoByModuleInfo, G as Global, x as getGlobalSnapshot, y as formatShareConfigs, z as getTargetSharedOptions, A as getGlobalShareScope, B as addUniqueItem, C as getBuilderId, E as setGlobalFederationConstructor, F as getGlobalFederationInstance, H as getGlobalFederationConstructor, I as setGlobalFederationInstance } from './share.esm.js';
2
2
  export { J as registerGlobalPlugins } from './share.esm.js';
3
- import { loadScriptNode, loadScript, composeKeyWithSeparator, createLink, createScript, getResourceUrl, isManifestProvider, generateSnapshotFromManifest, warn as warn$1, isBrowserEnv as isBrowserEnv$1 } from '@module-federation/sdk';
3
+ import { isBrowserEnv, loadScriptNode, composeKeyWithSeparator, loadScript, createLink, createScript, getResourceUrl, isManifestProvider, generateSnapshotFromManifest, warn as warn$1 } from '@module-federation/sdk';
4
4
  export { loadScript, loadScriptNode } from '@module-federation/sdk';
5
5
 
6
6
  // Function to match a remote with its name and expose
@@ -140,29 +140,80 @@ async function loadEntryScript({ name, globalName, entry, createScriptHook }) {
140
140
  if (remoteEntryExports) {
141
141
  return remoteEntryExports;
142
142
  }
143
- if (typeof document === 'undefined') {
144
- return loadScriptNode(entry, {
145
- attrs: {
146
- name,
147
- globalName
148
- },
149
- createScriptHook
150
- }).then(()=>{
151
- const { remoteEntryKey, entryExports } = getRemoteEntryExports(name, globalName);
152
- assert(entryExports, `
153
- Unable to use the ${name}'s '${entry}' URL with ${remoteEntryKey}'s globalName to get remoteEntry exports.
154
- Possible reasons could be:\n
155
- 1. '${entry}' is not the correct URL, or the remoteEntry resource or name is incorrect.\n
156
- 2. ${remoteEntryKey} cannot be used to get remoteEntry exports in the window object.
157
- `);
158
- return entryExports;
159
- }).catch((e)=>{
160
- throw e;
161
- });
162
- }
163
143
  return loadScript(entry, {
164
144
  attrs: {},
165
- createScriptHook
145
+ createScriptHook: (url, attrs)=>{
146
+ const res = createScriptHook.emit({
147
+ url,
148
+ attrs
149
+ });
150
+ if (!res) return;
151
+ if (res instanceof HTMLScriptElement) {
152
+ return res;
153
+ }
154
+ if ('script' in res || 'timeout' in res) {
155
+ return res;
156
+ }
157
+ return;
158
+ }
159
+ }).then(()=>{
160
+ const { remoteEntryKey, entryExports } = getRemoteEntryExports(name, globalName);
161
+ assert(entryExports, `
162
+ Unable to use the ${name}'s '${entry}' URL with ${remoteEntryKey}'s globalName to get remoteEntry exports.
163
+ Possible reasons could be:\n
164
+ 1. '${entry}' is not the correct URL, or the remoteEntry resource or name is incorrect.\n
165
+ 2. ${remoteEntryKey} cannot be used to get remoteEntry exports in the window object.
166
+ `);
167
+ return entryExports;
168
+ }).catch((e)=>{
169
+ throw e;
170
+ });
171
+ }
172
+ async function loadEntryDom({ remoteInfo, remoteEntryExports, createScriptHook }) {
173
+ const { entry, entryGlobalName: globalName, name, type } = remoteInfo;
174
+ switch(type){
175
+ case 'esm':
176
+ case 'module':
177
+ return loadEsmEntry({
178
+ entry,
179
+ remoteEntryExports
180
+ });
181
+ case 'system':
182
+ return loadSystemJsEntry({
183
+ entry,
184
+ remoteEntryExports
185
+ });
186
+ default:
187
+ return loadEntryScript({
188
+ entry,
189
+ globalName,
190
+ name,
191
+ createScriptHook
192
+ });
193
+ }
194
+ }
195
+ async function loadEntryNode({ remoteInfo, createScriptHook }) {
196
+ const { entry, entryGlobalName: globalName, name } = remoteInfo;
197
+ const { entryExports: remoteEntryExports } = getRemoteEntryExports(name, globalName);
198
+ if (remoteEntryExports) {
199
+ return remoteEntryExports;
200
+ }
201
+ return loadScriptNode(entry, {
202
+ attrs: {
203
+ name,
204
+ globalName
205
+ },
206
+ createScriptHook: (url, attrs)=>{
207
+ const res = createScriptHook.emit({
208
+ url,
209
+ attrs
210
+ });
211
+ if (!res) return;
212
+ if ('url' in res) {
213
+ return res;
214
+ }
215
+ return;
216
+ }
166
217
  }).then(()=>{
167
218
  const { remoteEntryKey, entryExports } = getRemoteEntryExports(name, globalName);
168
219
  assert(entryExports, `
@@ -180,33 +231,33 @@ function getRemoteEntryUniqueKey(remoteInfo) {
180
231
  const { entry, name } = remoteInfo;
181
232
  return composeKeyWithSeparator(name, entry);
182
233
  }
183
- async function getRemoteEntry({ remoteEntryExports, remoteInfo, createScriptHook }) {
184
- const { entry, name, type, entryGlobalName } = remoteInfo;
234
+ async function getRemoteEntry({ origin, remoteEntryExports, remoteInfo }) {
185
235
  const uniqueKey = getRemoteEntryUniqueKey(remoteInfo);
186
236
  if (remoteEntryExports) {
187
237
  return remoteEntryExports;
188
238
  }
189
239
  if (!globalLoading[uniqueKey]) {
190
- if ([
191
- 'esm',
192
- 'module'
193
- ].includes(type)) {
194
- globalLoading[uniqueKey] = loadEsmEntry({
195
- entry,
196
- remoteEntryExports
197
- });
198
- } else if (type === 'system') {
199
- globalLoading[uniqueKey] = loadSystemJsEntry({
200
- entry,
240
+ const loadEntryHook = origin.remoteHandler.hooks.lifecycle.loadEntry;
241
+ if (loadEntryHook.listeners.size) {
242
+ globalLoading[uniqueKey] = loadEntryHook.emit({
243
+ createScriptHook: origin.loaderHook.lifecycle.createScript,
244
+ remoteInfo,
201
245
  remoteEntryExports
202
- });
246
+ }).then((res)=>res || undefined);
203
247
  } else {
204
- globalLoading[uniqueKey] = loadEntryScript({
205
- name,
206
- globalName: entryGlobalName,
207
- entry,
208
- createScriptHook
209
- });
248
+ const createScriptHook = origin.loaderHook.lifecycle.createScript;
249
+ if (!isBrowserEnv()) {
250
+ globalLoading[uniqueKey] = loadEntryNode({
251
+ remoteInfo,
252
+ createScriptHook
253
+ });
254
+ } else {
255
+ globalLoading[uniqueKey] = loadEntryDom({
256
+ remoteInfo,
257
+ remoteEntryExports,
258
+ createScriptHook
259
+ });
260
+ }
210
261
  }
211
262
  }
212
263
  return globalLoading[uniqueKey];
@@ -241,26 +292,9 @@ let Module = class Module {
241
292
  }
242
293
  // Get remoteEntry.js
243
294
  const remoteEntryExports = await getRemoteEntry({
295
+ origin: this.host,
244
296
  remoteInfo: this.remoteInfo,
245
- remoteEntryExports: this.remoteEntryExports,
246
- createScriptHook: (url, attrs)=>{
247
- const res = this.host.loaderHook.lifecycle.createScript.emit({
248
- url,
249
- attrs
250
- });
251
- if (!res) return;
252
- if (typeof document === 'undefined') {
253
- //todo: needs real fix
254
- return res;
255
- }
256
- if (res instanceof HTMLScriptElement) {
257
- return res;
258
- }
259
- if ('script' in res || 'timeout' in res) {
260
- return res;
261
- }
262
- return;
263
- }
297
+ remoteEntryExports: this.remoteEntryExports
264
298
  });
265
299
  assert(remoteEntryExports, `remoteEntryExports is undefined \n ${safeToString(this.remoteInfo)}`);
266
300
  this.remoteEntryExports = remoteEntryExports;
@@ -596,49 +630,15 @@ useLinkPreload = true) {
596
630
  const module = host.moduleCache.get(remoteInfo.name);
597
631
  if (module) {
598
632
  getRemoteEntry({
633
+ origin: host,
599
634
  remoteInfo: moduleInfo,
600
- remoteEntryExports: module.remoteEntryExports,
601
- createScriptHook: (url, attrs)=>{
602
- const res = host.loaderHook.lifecycle.createScript.emit({
603
- url,
604
- attrs
605
- });
606
- if (!res) return;
607
- if (typeof document === 'undefined') {
608
- //todo: needs real fix
609
- return res;
610
- }
611
- if (res instanceof HTMLScriptElement) {
612
- return res;
613
- }
614
- if ('script' in res || 'timeout' in res) {
615
- return res;
616
- }
617
- return;
618
- }
635
+ remoteEntryExports: module.remoteEntryExports
619
636
  });
620
637
  } else {
621
638
  getRemoteEntry({
639
+ origin: host,
622
640
  remoteInfo: moduleInfo,
623
- remoteEntryExports: undefined,
624
- createScriptHook: (url, attrs)=>{
625
- const res = host.loaderHook.lifecycle.createScript.emit({
626
- url,
627
- attrs
628
- });
629
- if (!res) return;
630
- if (typeof document === 'undefined') {
631
- //todo: needs real fix
632
- return res;
633
- }
634
- if (res instanceof HTMLScriptElement) {
635
- return res;
636
- }
637
- if ('script' in res || 'timeout' in res) {
638
- return res;
639
- }
640
- return;
641
- }
641
+ remoteEntryExports: undefined
642
642
  });
643
643
  }
644
644
  });
@@ -763,7 +763,7 @@ function assignRemoteInfo(remoteInfo, remoteSnapshot) {
763
763
  error(`The attribute remoteEntry of ${remoteInfo.name} must not be undefined.`);
764
764
  }
765
765
  let entryUrl = getResourceUrl(remoteSnapshot, remoteEntryInfo.url);
766
- if (!isBrowserEnv() && !entryUrl.startsWith('http')) {
766
+ if (!isBrowserEnv$1() && !entryUrl.startsWith('http')) {
767
767
  entryUrl = `https:${entryUrl}`;
768
768
  }
769
769
  remoteInfo.type = remoteEntryInfo.type;
@@ -1121,10 +1121,12 @@ class SnapshotHandler {
1121
1121
  remoteSnapshot,
1122
1122
  globalSnapshot
1123
1123
  });
1124
+ let mSnapshot;
1125
+ let gSnapshot;
1124
1126
  // global snapshot includes manifest or module info includes manifest
1125
1127
  if (globalRemoteSnapshot) {
1126
1128
  if (isManifestProvider(globalRemoteSnapshot)) {
1127
- const remoteEntry = isBrowserEnv() ? globalRemoteSnapshot.remoteEntry : globalRemoteSnapshot.ssrRemoteEntry || globalRemoteSnapshot.remoteEntry || '';
1129
+ const remoteEntry = isBrowserEnv$1() ? globalRemoteSnapshot.remoteEntry : globalRemoteSnapshot.ssrRemoteEntry || globalRemoteSnapshot.remoteEntry || '';
1128
1130
  const moduleSnapshot = await this.getManifestJson(remoteEntry, moduleInfo, {});
1129
1131
  // eslint-disable-next-line @typescript-eslint/no-shadow
1130
1132
  const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(_extends$3({}, moduleInfo, {
@@ -1132,10 +1134,8 @@ class SnapshotHandler {
1132
1134
  // Therefore, set the snapshot key to the global address of the actual request
1133
1135
  entry: remoteEntry
1134
1136
  }), moduleSnapshot);
1135
- return {
1136
- remoteSnapshot: moduleSnapshot,
1137
- globalSnapshot: globalSnapshotRes
1138
- };
1137
+ mSnapshot = moduleSnapshot;
1138
+ gSnapshot = globalSnapshotRes;
1139
1139
  } else {
1140
1140
  const { remoteSnapshot: remoteSnapshotRes } = await this.hooks.lifecycle.loadRemoteSnapshot.emit({
1141
1141
  options: this.HostInstance.options,
@@ -1143,10 +1143,8 @@ class SnapshotHandler {
1143
1143
  remoteSnapshot: globalRemoteSnapshot,
1144
1144
  from: 'global'
1145
1145
  });
1146
- return {
1147
- remoteSnapshot: remoteSnapshotRes,
1148
- globalSnapshot: globalSnapshotRes
1149
- };
1146
+ mSnapshot = remoteSnapshotRes;
1147
+ gSnapshot = globalSnapshotRes;
1150
1148
  }
1151
1149
  } else {
1152
1150
  if (isRemoteInfoWithEntry(moduleInfo)) {
@@ -1160,10 +1158,8 @@ class SnapshotHandler {
1160
1158
  remoteSnapshot: moduleSnapshot,
1161
1159
  from: 'global'
1162
1160
  });
1163
- return {
1164
- remoteSnapshot: remoteSnapshotRes,
1165
- globalSnapshot: globalSnapshotRes
1166
- };
1161
+ mSnapshot = remoteSnapshotRes;
1162
+ gSnapshot = globalSnapshotRes;
1167
1163
  } else {
1168
1164
  error(`
1169
1165
  Cannot get remoteSnapshot with the name: '${moduleInfo.name}', version: '${moduleInfo.version}' from __FEDERATION__.moduleInfo. The following reasons may be causing the problem:\n
@@ -1173,6 +1169,10 @@ class SnapshotHandler {
1173
1169
  `);
1174
1170
  }
1175
1171
  }
1172
+ return {
1173
+ remoteSnapshot: mSnapshot,
1174
+ globalSnapshot: gSnapshot
1175
+ };
1176
1176
  }
1177
1177
  getGlobalRemoteInfo(moduleInfo) {
1178
1178
  return getGlobalRemoteInfo(moduleInfo, this.HostInstance);
@@ -1225,7 +1225,8 @@ class SnapshotHandler {
1225
1225
  this.hooks = new PluginSystem({
1226
1226
  beforeLoadRemoteSnapshot: new AsyncHook('beforeLoadRemoteSnapshot'),
1227
1227
  loadSnapshot: new AsyncWaterfallHook('loadGlobalSnapshot'),
1228
- loadRemoteSnapshot: new AsyncWaterfallHook('loadRemoteSnapshot')
1228
+ loadRemoteSnapshot: new AsyncWaterfallHook('loadRemoteSnapshot'),
1229
+ afterLoadSnapshot: new AsyncWaterfallHook('loadRemoteSnapshot')
1229
1230
  });
1230
1231
  this.manifestLoading = Global.__FEDERATION__.__MANIFEST_LOADING__;
1231
1232
  this.HostInstance = HostInstance;
@@ -1795,7 +1796,7 @@ class RemoteHandler {
1795
1796
  }
1796
1797
  // Set the remote entry to a complete path
1797
1798
  if ('entry' in remote) {
1798
- if (isBrowserEnv$1() && !remote.entry.startsWith('http')) {
1799
+ if (isBrowserEnv() && !remote.entry.startsWith('http')) {
1799
1800
  remote.entry = new URL(remote.entry, window.location.origin).href;
1800
1801
  }
1801
1802
  }
@@ -1948,7 +1949,8 @@ class RemoteHandler {
1948
1949
  beforePreloadRemote: new AsyncHook('beforePreloadRemote'),
1949
1950
  generatePreloadAssets: new AsyncHook('generatePreloadAssets'),
1950
1951
  // not used yet
1951
- afterPreloadRemote: new AsyncHook()
1952
+ afterPreloadRemote: new AsyncHook(),
1953
+ loadEntry: new AsyncHook()
1952
1954
  });
1953
1955
  this.host = host;
1954
1956
  this.idToRemoteMap = {};
@@ -2095,7 +2097,7 @@ class FederationHost {
2095
2097
  ],
2096
2098
  remotes: [],
2097
2099
  shared: {},
2098
- inBrowser: isBrowserEnv()
2100
+ inBrowser: isBrowserEnv$1()
2099
2101
  };
2100
2102
  this.name = userOptions.name;
2101
2103
  this.options = defaultOptions;
package/dist/package.json CHANGED
@@ -29,11 +29,6 @@
29
29
  "import": "./dist/types.esm.js",
30
30
  "require": "./dist/types.cjs.js"
31
31
  },
32
- "./retry-plugin": {
33
- "types": "./dist/retry-plugin.cjs.d.ts",
34
- "import": "./dist/retry-plugin.esm.js",
35
- "require": "./dist/retry-plugin.cjs.js"
36
- },
37
32
  "./*": "./*"
38
33
  },
39
34
  "typesVersions": {
@@ -46,9 +41,6 @@
46
41
  ],
47
42
  "types": [
48
43
  "./dist/types.cjs.d.ts"
49
- ],
50
- "retry-plugin": [
51
- "./dist/retry-plugin.cjs.d.ts"
52
44
  ]
53
45
  }
54
46
  },
@@ -32,6 +32,11 @@ export declare class SnapshotHandler {
32
32
  remoteSnapshot: ModuleInfo;
33
33
  from: "global" | "manifest";
34
34
  }>;
35
+ afterLoadSnapshot: AsyncWaterfallHook<{
36
+ options: Options;
37
+ moduleInfo: Remote;
38
+ remoteSnapshot: ModuleInfo;
39
+ }>;
35
40
  }>;
36
41
  loaderHook: FederationHost['loaderHook'];
37
42
  manifestLoading: Record<string, Promise<ModuleInfo>>;
@@ -1,5 +1,5 @@
1
1
  import type { ModuleInfo, GlobalModuleInfo } from '@module-federation/sdk';
2
- import { Options, UserOptions, PreloadAssets, PreloadOptions, PreloadRemoteArgs, Remote, RemoteInfo } from '../type';
2
+ import { Options, UserOptions, PreloadAssets, PreloadOptions, PreloadRemoteArgs, Remote, RemoteInfo, RemoteEntryExports } from '../type';
3
3
  import { FederationHost } from '../core';
4
4
  import { PluginSystem, AsyncHook, AsyncWaterfallHook, SyncHook, SyncWaterfallHook } from '../utils/hooks';
5
5
  import { Module, ModuleOptions } from '../module';
@@ -78,6 +78,11 @@ export declare class RemoteHandler {
78
78
  options: Options;
79
79
  origin: FederationHost;
80
80
  }, false | void | Promise<false | void>>;
81
+ loadEntry: AsyncHook<[{
82
+ createScriptHook: FederationHost["loaderHook"]["lifecycle"]["createScript"];
83
+ remoteInfo: RemoteInfo;
84
+ remoteEntryExports?: RemoteEntryExports;
85
+ }], Promise<RemoteEntryExports>>;
81
86
  }>;
82
87
  constructor(host: FederationHost);
83
88
  formatAndRegisterRemote(globalOptions: Options, userOptions: UserOptions): Remote[];
@@ -1,23 +1,9 @@
1
- import { CreateScriptHookReturn } from '@module-federation/sdk';
1
+ import { FederationHost } from '../core';
2
2
  import { Remote, RemoteEntryExports, RemoteInfo } from '../type';
3
- export declare function loadEsmEntry({ entry, remoteEntryExports, }: {
4
- entry: string;
5
- remoteEntryExports: RemoteEntryExports | undefined;
6
- }): Promise<RemoteEntryExports>;
7
- export declare function loadSystemJsEntry({ entry, remoteEntryExports, }: {
8
- entry: string;
9
- remoteEntryExports: RemoteEntryExports | undefined;
10
- }): Promise<RemoteEntryExports>;
11
- export declare function loadEntryScript({ name, globalName, entry, createScriptHook, }: {
12
- name: string;
13
- globalName: string;
14
- entry: string;
15
- createScriptHook?: (url: string, attrs?: Record<string, any> | undefined) => CreateScriptHookReturn;
16
- }): Promise<RemoteEntryExports>;
17
3
  export declare function getRemoteEntryUniqueKey(remoteInfo: RemoteInfo): string;
18
- export declare function getRemoteEntry({ remoteEntryExports, remoteInfo, createScriptHook, }: {
4
+ export declare function getRemoteEntry({ origin, remoteEntryExports, remoteInfo, }: {
5
+ origin: FederationHost;
19
6
  remoteInfo: RemoteInfo;
20
7
  remoteEntryExports?: RemoteEntryExports | undefined;
21
- createScriptHook?: (url: string, attrs?: Record<string, any> | undefined) => CreateScriptHookReturn;
22
- }): Promise<RemoteEntryExports | void>;
8
+ }): Promise<RemoteEntryExports | false | void>;
23
9
  export declare function getRemoteInfo(remote: Remote): RemoteInfo;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@module-federation/runtime",
3
- "version": "0.0.0-next-20240814104132",
3
+ "version": "0.0.0-next-20240815093707",
4
4
  "author": "zhouxiao <codingzx@gmail.com>",
5
5
  "main": "./dist/index.cjs.js",
6
6
  "module": "./dist/index.esm.js",
@@ -29,11 +29,6 @@
29
29
  "import": "./dist/types.esm.js",
30
30
  "require": "./dist/types.cjs.js"
31
31
  },
32
- "./retry-plugin": {
33
- "types": "./dist/retry-plugin.cjs.d.ts",
34
- "import": "./dist/retry-plugin.esm.js",
35
- "require": "./dist/retry-plugin.cjs.js"
36
- },
37
32
  "./*": "./*"
38
33
  },
39
34
  "typesVersions": {
@@ -46,13 +41,10 @@
46
41
  ],
47
42
  "types": [
48
43
  "./dist/types.cjs.d.ts"
49
- ],
50
- "retry-plugin": [
51
- "./dist/retry-plugin.cjs.d.ts"
52
44
  ]
53
45
  }
54
46
  },
55
47
  "dependencies": {
56
- "@module-federation/sdk": "0.0.0-next-20240814104132"
48
+ "@module-federation/sdk": "0.0.0-next-20240815093707"
57
49
  }
58
50
  }
@@ -1,2 +0,0 @@
1
- export * from "./src/plugins/retry-plugin";
2
- export { default } from "./src/plugins/retry-plugin";
@@ -1,68 +0,0 @@
1
- 'use strict';
2
-
3
- function _extends() {
4
- _extends = Object.assign || function(target) {
5
- for(var i = 1; i < arguments.length; i++){
6
- var source = arguments[i];
7
- for(var key in source){
8
- if (Object.prototype.hasOwnProperty.call(source, key)) {
9
- target[key] = source[key];
10
- }
11
- }
12
- }
13
- return target;
14
- };
15
- return _extends.apply(this, arguments);
16
- }
17
- const defaultRetries = 3;
18
- async function fetchWithRetry({ url, options = {}, retryTimes = defaultRetries, fallbackUrl = '' }) {
19
- try {
20
- const response = await fetch(url, options);
21
- // To prevent the response object from being read multiple times and causing errors, clone it
22
- const responseClone = response.clone();
23
- // Network error
24
- if (!response.ok) {
25
- throw new Error(`Server error:${response.status}`);
26
- }
27
- // parse json error
28
- await responseClone.json().catch((error)=>{
29
- throw new Error(`Json parse error: ${error}, url is: ${url}`);
30
- });
31
- return response;
32
- } catch (error) {
33
- if (retryTimes <= 0) {
34
- console.log(`>>>>>>>>> retry failed after ${defaultRetries} times for url: ${url}, now will try fallbackUrl url: ${fallbackUrl} <<<<<<<<<`);
35
- if (fallbackUrl && fallbackUrl !== url) {
36
- return fetchWithRetry({
37
- url: fallbackUrl,
38
- options,
39
- retryTimes: 1,
40
- fallbackUrl
41
- });
42
- }
43
- throw new Error('The request failed three times and has now been abandoned');
44
- }
45
- // If there are remaining times, delay 1 second and try again
46
- await new Promise((resolve)=>setTimeout(resolve, 1000));
47
- console.log(`Trying again. Number of retries available:${retryTimes - 1}`);
48
- return await fetchWithRetry({
49
- url,
50
- options,
51
- retryTimes: retryTimes - 1,
52
- fallbackUrl
53
- });
54
- }
55
- }
56
- const RetryPlugin = (params)=>({
57
- name: 'retry-plugin',
58
- async fetch (url, options) {
59
- return fetchWithRetry({
60
- url,
61
- options: _extends({}, options, params == null ? void 0 : params.options),
62
- retryTimes: params == null ? void 0 : params.retryTimes,
63
- fallbackUrl: params == null ? void 0 : params.fallbackUrl
64
- });
65
- }
66
- });
67
-
68
- module.exports = RetryPlugin;
@@ -1,66 +0,0 @@
1
- function _extends() {
2
- _extends = Object.assign || function(target) {
3
- for(var i = 1; i < arguments.length; i++){
4
- var source = arguments[i];
5
- for(var key in source){
6
- if (Object.prototype.hasOwnProperty.call(source, key)) {
7
- target[key] = source[key];
8
- }
9
- }
10
- }
11
- return target;
12
- };
13
- return _extends.apply(this, arguments);
14
- }
15
- const defaultRetries = 3;
16
- async function fetchWithRetry({ url, options = {}, retryTimes = defaultRetries, fallbackUrl = '' }) {
17
- try {
18
- const response = await fetch(url, options);
19
- // To prevent the response object from being read multiple times and causing errors, clone it
20
- const responseClone = response.clone();
21
- // Network error
22
- if (!response.ok) {
23
- throw new Error(`Server error:${response.status}`);
24
- }
25
- // parse json error
26
- await responseClone.json().catch((error)=>{
27
- throw new Error(`Json parse error: ${error}, url is: ${url}`);
28
- });
29
- return response;
30
- } catch (error) {
31
- if (retryTimes <= 0) {
32
- console.log(`>>>>>>>>> retry failed after ${defaultRetries} times for url: ${url}, now will try fallbackUrl url: ${fallbackUrl} <<<<<<<<<`);
33
- if (fallbackUrl && fallbackUrl !== url) {
34
- return fetchWithRetry({
35
- url: fallbackUrl,
36
- options,
37
- retryTimes: 1,
38
- fallbackUrl
39
- });
40
- }
41
- throw new Error('The request failed three times and has now been abandoned');
42
- }
43
- // If there are remaining times, delay 1 second and try again
44
- await new Promise((resolve)=>setTimeout(resolve, 1000));
45
- console.log(`Trying again. Number of retries available:${retryTimes - 1}`);
46
- return await fetchWithRetry({
47
- url,
48
- options,
49
- retryTimes: retryTimes - 1,
50
- fallbackUrl
51
- });
52
- }
53
- }
54
- const RetryPlugin = (params)=>({
55
- name: 'retry-plugin',
56
- async fetch (url, options) {
57
- return fetchWithRetry({
58
- url,
59
- options: _extends({}, options, params == null ? void 0 : params.options),
60
- retryTimes: params == null ? void 0 : params.retryTimes,
61
- fallbackUrl: params == null ? void 0 : params.fallbackUrl
62
- });
63
- }
64
- });
65
-
66
- export { RetryPlugin as default };
@@ -1,9 +0,0 @@
1
- import { FederationRuntimePlugin } from '../type/plugin';
2
- interface FetchWithRetryOptions {
3
- url: string;
4
- options?: RequestInit;
5
- retryTimes?: number;
6
- fallbackUrl?: string;
7
- }
8
- declare const RetryPlugin: (params?: Omit<FetchWithRetryOptions, 'url'>) => FederationRuntimePlugin;
9
- export default RetryPlugin;