remote-reload-utils 0.0.16 → 0.0.17
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/CHANGELOG.md +9 -0
- package/dist/index.d.ts +2 -2
- package/dist/loader/index.d.ts +4 -2
- package/dist/loader/remote-source/index.d.ts +28 -0
- package/dist/loader/utils.d.ts +6 -2
- package/dist/main.cjs +84 -38
- package/dist/main.js +82 -39
- package/dist/types/index.d.ts +1 -1
- package/loadRemote.md +67 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,13 @@
|
|
|
7
7
|
|
|
8
8
|
## [未发布]
|
|
9
9
|
|
|
10
|
+
## [0.0.17] - 2026-03-19
|
|
11
|
+
|
|
12
|
+
### Release
|
|
13
|
+
|
|
14
|
+
- Published version 0.0.17 with patch bump
|
|
15
|
+
|
|
16
|
+
|
|
10
17
|
## [0.0.16] - 2026-03-18
|
|
11
18
|
|
|
12
19
|
### Release
|
|
@@ -172,6 +179,8 @@
|
|
|
172
179
|
|
|
173
180
|
| 版本 | 日期 | 主要变更 |
|
|
174
181
|
|------|------|----------|
|
|
182
|
+
| 0.0.17 | 2026-03-19 | patch 版本发布 |
|
|
183
|
+
|------|------|----------|
|
|
175
184
|
| 0.0.16 | 2026-03-18 | patch 版本发布 |
|
|
176
185
|
|------|------|----------|
|
|
177
186
|
| 0.0.15 | 2026-03-17 | patch 版本发布 |
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { loadReactVersion } from './version/react';
|
|
2
2
|
export { checkVersionCompatibility, satisfiesVersion, findCompatibleVersion, getCompatibleReactVersions, fetchAvailableVersions, sortVersions, getLatestVersion, getStableVersions, extractMajorVersion, isPrerelease, compareVersions, parseVersion, } from './version';
|
|
3
|
-
export { loadRemoteMultiVersion } from './loader';
|
|
4
|
-
export { fetchLatestVersion, getVersionCache, setVersionCache, buildCdnUrls, tryLoadRemote, getFinalSharedConfig, resolveFinalVersion, buildFinalUrls, type LoadResult, } from './loader/utils';
|
|
3
|
+
export { loadRemoteMultiVersion, createRemoteSourcePlugin, type RemoteSourcePlugin, type RemoteSourcePluginContext, type LoadRemoteExtraOptions, } from './loader';
|
|
4
|
+
export { fetchLatestVersion, getVersionCache, setVersionCache, buildCdnUrls, tryLoadRemote, getFinalSharedConfig, resolveFinalVersion, buildFinalUrls, type LoadResult, type RuntimeRemote, } from './loader/utils';
|
|
5
5
|
export { preloadRemote, preloadRemoteList, cancelPreload, clearPreloadCache, getPreloadStatus, } from './preload';
|
|
6
6
|
export { unloadRemote, unloadAll, registerRemoteInstance, registerLoadedModule, getLoadedRemotes, isRemoteLoaded, } from './unload';
|
|
7
7
|
export { checkRemoteHealth, checkModuleLoadable, getRemoteHealthReport, formatHealthStatus, } from './health';
|
package/dist/loader/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { ModuleFederationRuntimePlugin } from '@module-federation/enhanced/runtime';
|
|
1
|
+
import type { ModuleFederationRuntimePlugin } from '@module-federation/enhanced/runtime';
|
|
2
2
|
import type { LoadRemoteOptions } from '../types';
|
|
3
|
+
import { createRemoteSourcePlugin, type LoadRemoteExtraOptions, type RemoteSourcePlugin, type RemoteSourcePluginContext } from './remote-source';
|
|
4
|
+
export { createRemoteSourcePlugin, type RemoteSourcePlugin, type RemoteSourcePluginContext, type LoadRemoteExtraOptions, };
|
|
3
5
|
/**
|
|
4
6
|
* 多版本共存的 loadRemote
|
|
5
7
|
*/
|
|
6
|
-
export declare function loadRemoteMultiVersion(options: LoadRemoteOptions, plugins
|
|
8
|
+
export declare function loadRemoteMultiVersion(options: LoadRemoteOptions, plugins?: ModuleFederationRuntimePlugin[], extraOptions?: LoadRemoteExtraOptions): Promise<import("./utils").LoadResult>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { LoadRemoteOptions } from '../../types';
|
|
2
|
+
import type { RuntimeRemote } from '../utils';
|
|
3
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
4
|
+
export interface RemoteSourcePluginContext {
|
|
5
|
+
options: LoadRemoteOptions;
|
|
6
|
+
scopeName: string;
|
|
7
|
+
pkg: string;
|
|
8
|
+
finalVersion: string;
|
|
9
|
+
currentEntry: string;
|
|
10
|
+
allEntries: string[];
|
|
11
|
+
}
|
|
12
|
+
export interface RemoteSourcePlugin {
|
|
13
|
+
name: string;
|
|
14
|
+
registerRemotes?: (context: RemoteSourcePluginContext) => MaybePromise<RuntimeRemote[] | void>;
|
|
15
|
+
}
|
|
16
|
+
export interface LoadRemoteExtraOptions {
|
|
17
|
+
remoteSourcePlugins?: RemoteSourcePlugin[];
|
|
18
|
+
baseRemotes?: RuntimeRemote[];
|
|
19
|
+
registerOptions?: {
|
|
20
|
+
force?: boolean;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export declare function resolveRegisteredRemotes(context: RemoteSourcePluginContext, baseRemotes: RuntimeRemote[], remoteSourcePlugins: RemoteSourcePlugin[]): Promise<RuntimeRemote[]>;
|
|
24
|
+
/**
|
|
25
|
+
* 创建静态 remote 来源插件
|
|
26
|
+
*/
|
|
27
|
+
export declare function createRemoteSourcePlugin(name: string, remotes: RuntimeRemote[]): RemoteSourcePlugin;
|
|
28
|
+
export {};
|
package/dist/loader/utils.d.ts
CHANGED
|
@@ -20,10 +20,14 @@ export interface LoadResult {
|
|
|
20
20
|
scopeName: string;
|
|
21
21
|
mf: ReturnType<typeof createInstance>;
|
|
22
22
|
}
|
|
23
|
+
export type RuntimeRemote = Parameters<ReturnType<typeof createInstance>['registerRemotes']>[0][number];
|
|
23
24
|
/**
|
|
24
|
-
* 尝试加载单个远程模块 URL
|
|
25
|
+
* 尝试加载单个远程模块 URL
|
|
26
|
+
* 注意:实际的重试机制在外层 loadRemoteMultiVersion 的 URL 遍历中实现
|
|
25
27
|
*/
|
|
26
|
-
export declare function tryLoadRemote(scopeName: string, url: string,
|
|
28
|
+
export declare function tryLoadRemote(scopeName: string, url: string, _retries: number, _delay: number, sharedConfig: Record<string, any>, plugins: ModuleFederationRuntimePlugin[], extraRemotes?: RuntimeRemote[], registerOptions?: {
|
|
29
|
+
force?: boolean;
|
|
30
|
+
}): Promise<LoadResult>;
|
|
27
31
|
/**
|
|
28
32
|
* 获取最终的共享配置
|
|
29
33
|
*/
|
package/dist/main.cjs
CHANGED
|
@@ -60,6 +60,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
60
60
|
satisfiesVersion: ()=>satisfiesVersion,
|
|
61
61
|
formatHealthStatus: ()=>formatHealthStatus,
|
|
62
62
|
unloadAll: ()=>unloadAll,
|
|
63
|
+
createRemoteSourcePlugin: ()=>createRemoteSourcePlugin,
|
|
63
64
|
setVersionCache: ()=>setVersionCache,
|
|
64
65
|
isPrerelease: ()=>isPrerelease,
|
|
65
66
|
checkRemoteHealth: ()=>checkRemoteHealth,
|
|
@@ -323,8 +324,20 @@ function buildCdnUrls(pkg, version) {
|
|
|
323
324
|
}
|
|
324
325
|
const mfInstanceCache = new Map();
|
|
325
326
|
const mfInstanceLoadingCache = new Map();
|
|
326
|
-
|
|
327
|
-
|
|
327
|
+
function buildRemotesIdentity(remotes) {
|
|
328
|
+
if (0 === remotes.length) return '';
|
|
329
|
+
return remotes.map((remote)=>JSON.stringify({
|
|
330
|
+
name: remote.name,
|
|
331
|
+
entry: 'entry' in remote ? remote.entry : '',
|
|
332
|
+
version: 'version' in remote ? remote.version : '',
|
|
333
|
+
alias: remote.alias || '',
|
|
334
|
+
type: remote.type || '',
|
|
335
|
+
entryGlobalName: remote.entryGlobalName || ''
|
|
336
|
+
})).sort().join('|');
|
|
337
|
+
}
|
|
338
|
+
async function tryLoadRemote(scopeName, url, _retries, _delay, sharedConfig, plugins, extraRemotes = [], registerOptions = {}) {
|
|
339
|
+
const remotesIdentity = buildRemotesIdentity(extraRemotes);
|
|
340
|
+
const cacheKey = `${scopeName}::${url}::${remotesIdentity}::${registerOptions.force ? 'force' : 'normal'}`;
|
|
328
341
|
const cachedMfs = mfInstanceCache.get(cacheKey);
|
|
329
342
|
if (cachedMfs) return {
|
|
330
343
|
scopeName,
|
|
@@ -332,41 +345,32 @@ async function tryLoadRemote(scopeName, url, retries, delay, sharedConfig, plugi
|
|
|
332
345
|
};
|
|
333
346
|
const loadingMfs = mfInstanceLoadingCache.get(cacheKey);
|
|
334
347
|
if (loadingMfs) return loadingMfs;
|
|
335
|
-
const
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
fallbackPlugin()
|
|
350
|
-
]
|
|
351
|
-
});
|
|
352
|
-
const result = {
|
|
353
|
-
scopeName,
|
|
354
|
-
mf
|
|
355
|
-
};
|
|
356
|
-
mfInstanceCache.set(cacheKey, mf);
|
|
357
|
-
return result;
|
|
358
|
-
} catch (e) {
|
|
359
|
-
lastError = e;
|
|
360
|
-
console.warn(`[MF] URL ${url} 加载失败,第 ${i + 1} 次重试...`);
|
|
361
|
-
if (i < retries - 1) await new Promise((res)=>setTimeout(res, delay));
|
|
362
|
-
}
|
|
363
|
-
throw new Error(`[MF] URL ${url} 经过 ${retries} 次重试仍加载失败。`, {
|
|
364
|
-
cause: lastError
|
|
348
|
+
const loadPromise = Promise.resolve().then(()=>{
|
|
349
|
+
const mf = (0, runtime_namespaceObject.createInstance)({
|
|
350
|
+
name: 'host',
|
|
351
|
+
remotes: [
|
|
352
|
+
{
|
|
353
|
+
name: scopeName,
|
|
354
|
+
entry: url
|
|
355
|
+
}
|
|
356
|
+
],
|
|
357
|
+
shared: sharedConfig,
|
|
358
|
+
plugins: [
|
|
359
|
+
...plugins,
|
|
360
|
+
fallbackPlugin()
|
|
361
|
+
]
|
|
365
362
|
});
|
|
366
|
-
|
|
367
|
-
|
|
363
|
+
if (extraRemotes.length > 0) mf.registerRemotes(extraRemotes, registerOptions);
|
|
364
|
+
const result = {
|
|
365
|
+
scopeName,
|
|
366
|
+
mf
|
|
367
|
+
};
|
|
368
|
+
mfInstanceCache.set(cacheKey, mf);
|
|
369
|
+
return result;
|
|
370
|
+
});
|
|
371
|
+
mfInstanceLoadingCache.set(cacheKey, loadPromise);
|
|
368
372
|
try {
|
|
369
|
-
return await
|
|
373
|
+
return await loadPromise;
|
|
370
374
|
} finally{
|
|
371
375
|
mfInstanceLoadingCache.delete(cacheKey);
|
|
372
376
|
}
|
|
@@ -488,15 +492,55 @@ function buildFinalUrls(pkg, version, localFallback) {
|
|
|
488
492
|
if (localFallback) urls.push(localFallback);
|
|
489
493
|
return urls;
|
|
490
494
|
}
|
|
491
|
-
|
|
495
|
+
function dedupeRemotes(remotes) {
|
|
496
|
+
const map = new Map();
|
|
497
|
+
for (const remote of remotes){
|
|
498
|
+
if (!remote?.name) continue;
|
|
499
|
+
const key = [
|
|
500
|
+
remote.name,
|
|
501
|
+
'entry' in remote ? remote.entry || '' : '',
|
|
502
|
+
'version' in remote ? remote.version || '' : '',
|
|
503
|
+
remote.alias || ''
|
|
504
|
+
].join('::');
|
|
505
|
+
if (!map.has(key)) map.set(key, remote);
|
|
506
|
+
}
|
|
507
|
+
return Array.from(map.values());
|
|
508
|
+
}
|
|
509
|
+
async function resolveRegisteredRemotes(context, baseRemotes, remoteSourcePlugins) {
|
|
510
|
+
const remoteList = [
|
|
511
|
+
...baseRemotes
|
|
512
|
+
];
|
|
513
|
+
for (const plugin of remoteSourcePlugins)if (plugin.registerRemotes) try {
|
|
514
|
+
const pluginRemotes = await plugin.registerRemotes(context);
|
|
515
|
+
if (pluginRemotes?.length) remoteList.push(...pluginRemotes);
|
|
516
|
+
} catch (error) {
|
|
517
|
+
throw new Error(`[MF] remote 来源插件 ${plugin.name} 执行失败: ${error.message}`);
|
|
518
|
+
}
|
|
519
|
+
return dedupeRemotes(remoteList).filter((remote)=>!(remote.name === context.scopeName && 'entry' in remote && remote.entry === context.currentEntry));
|
|
520
|
+
}
|
|
521
|
+
function createRemoteSourcePlugin(name, remotes) {
|
|
522
|
+
return {
|
|
523
|
+
name,
|
|
524
|
+
registerRemotes: ()=>remotes
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
async function loadRemoteMultiVersion(options, plugins = [], extraOptions = {}) {
|
|
492
528
|
const { name, pkg, version = 'latest', retries = 3, delay = 1000, localFallback, cacheTTL = 86400000, revalidate = true, shared: customShared } = options;
|
|
529
|
+
const { remoteSourcePlugins = [], baseRemotes = [], registerOptions = {} } = extraOptions;
|
|
493
530
|
const finalVersion = await resolveFinalVersion(pkg, version, cacheTTL, revalidate);
|
|
494
531
|
const scopeName = `${name}`;
|
|
495
532
|
const urls = buildFinalUrls(pkg, finalVersion, localFallback);
|
|
496
533
|
const finalSharedConfig = getFinalSharedConfig(customShared);
|
|
497
|
-
console.log(finalSharedConfig, 'finalSharedConfig');
|
|
498
534
|
for (const url of urls)try {
|
|
499
|
-
|
|
535
|
+
const registeredRemotes = await resolveRegisteredRemotes({
|
|
536
|
+
options,
|
|
537
|
+
scopeName,
|
|
538
|
+
pkg,
|
|
539
|
+
finalVersion,
|
|
540
|
+
currentEntry: url,
|
|
541
|
+
allEntries: urls
|
|
542
|
+
}, baseRemotes, remoteSourcePlugins);
|
|
543
|
+
return await tryLoadRemote(scopeName, url, retries, delay, finalSharedConfig, plugins, registeredRemotes, registerOptions);
|
|
500
544
|
} catch (e) {
|
|
501
545
|
console.warn(`[MF] 切换 CDN 路径:${url} 失败,尝试下一个...`, e);
|
|
502
546
|
}
|
|
@@ -897,6 +941,7 @@ exports.checkVersionCompatibility = __webpack_exports__.checkVersionCompatibilit
|
|
|
897
941
|
exports.clearPreloadCache = __webpack_exports__.clearPreloadCache;
|
|
898
942
|
exports.compareVersions = __webpack_exports__.compareVersions;
|
|
899
943
|
exports.createEventBus = __webpack_exports__.createEventBus;
|
|
944
|
+
exports.createRemoteSourcePlugin = __webpack_exports__.createRemoteSourcePlugin;
|
|
900
945
|
exports.eventBus = __webpack_exports__.eventBus;
|
|
901
946
|
exports.extractMajorVersion = __webpack_exports__.extractMajorVersion;
|
|
902
947
|
exports.fallbackPlugin = __webpack_exports__.fallbackPlugin;
|
|
@@ -938,6 +983,7 @@ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
|
938
983
|
"clearPreloadCache",
|
|
939
984
|
"compareVersions",
|
|
940
985
|
"createEventBus",
|
|
986
|
+
"createRemoteSourcePlugin",
|
|
941
987
|
"eventBus",
|
|
942
988
|
"extractMajorVersion",
|
|
943
989
|
"fallbackPlugin",
|
package/dist/main.js
CHANGED
|
@@ -256,8 +256,20 @@ function buildCdnUrls(pkg, version) {
|
|
|
256
256
|
}
|
|
257
257
|
const mfInstanceCache = new Map();
|
|
258
258
|
const mfInstanceLoadingCache = new Map();
|
|
259
|
-
|
|
260
|
-
|
|
259
|
+
function buildRemotesIdentity(remotes) {
|
|
260
|
+
if (0 === remotes.length) return '';
|
|
261
|
+
return remotes.map((remote)=>JSON.stringify({
|
|
262
|
+
name: remote.name,
|
|
263
|
+
entry: 'entry' in remote ? remote.entry : '',
|
|
264
|
+
version: 'version' in remote ? remote.version : '',
|
|
265
|
+
alias: remote.alias || '',
|
|
266
|
+
type: remote.type || '',
|
|
267
|
+
entryGlobalName: remote.entryGlobalName || ''
|
|
268
|
+
})).sort().join('|');
|
|
269
|
+
}
|
|
270
|
+
async function tryLoadRemote(scopeName, url, _retries, _delay, sharedConfig, plugins, extraRemotes = [], registerOptions = {}) {
|
|
271
|
+
const remotesIdentity = buildRemotesIdentity(extraRemotes);
|
|
272
|
+
const cacheKey = `${scopeName}::${url}::${remotesIdentity}::${registerOptions.force ? 'force' : 'normal'}`;
|
|
261
273
|
const cachedMfs = mfInstanceCache.get(cacheKey);
|
|
262
274
|
if (cachedMfs) return {
|
|
263
275
|
scopeName,
|
|
@@ -265,41 +277,32 @@ async function tryLoadRemote(scopeName, url, retries, delay, sharedConfig, plugi
|
|
|
265
277
|
};
|
|
266
278
|
const loadingMfs = mfInstanceLoadingCache.get(cacheKey);
|
|
267
279
|
if (loadingMfs) return loadingMfs;
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
fallbackPlugin()
|
|
283
|
-
]
|
|
284
|
-
});
|
|
285
|
-
const result = {
|
|
286
|
-
scopeName,
|
|
287
|
-
mf
|
|
288
|
-
};
|
|
289
|
-
mfInstanceCache.set(cacheKey, mf);
|
|
290
|
-
return result;
|
|
291
|
-
} catch (e) {
|
|
292
|
-
lastError = e;
|
|
293
|
-
console.warn(`[MF] URL ${url} 加载失败,第 ${i + 1} 次重试...`);
|
|
294
|
-
if (i < retries - 1) await new Promise((res)=>setTimeout(res, delay));
|
|
295
|
-
}
|
|
296
|
-
throw new Error(`[MF] URL ${url} 经过 ${retries} 次重试仍加载失败。`, {
|
|
297
|
-
cause: lastError
|
|
280
|
+
const loadPromise = Promise.resolve().then(()=>{
|
|
281
|
+
const mf = createInstance({
|
|
282
|
+
name: 'host',
|
|
283
|
+
remotes: [
|
|
284
|
+
{
|
|
285
|
+
name: scopeName,
|
|
286
|
+
entry: url
|
|
287
|
+
}
|
|
288
|
+
],
|
|
289
|
+
shared: sharedConfig,
|
|
290
|
+
plugins: [
|
|
291
|
+
...plugins,
|
|
292
|
+
fallbackPlugin()
|
|
293
|
+
]
|
|
298
294
|
});
|
|
299
|
-
|
|
300
|
-
|
|
295
|
+
if (extraRemotes.length > 0) mf.registerRemotes(extraRemotes, registerOptions);
|
|
296
|
+
const result = {
|
|
297
|
+
scopeName,
|
|
298
|
+
mf
|
|
299
|
+
};
|
|
300
|
+
mfInstanceCache.set(cacheKey, mf);
|
|
301
|
+
return result;
|
|
302
|
+
});
|
|
303
|
+
mfInstanceLoadingCache.set(cacheKey, loadPromise);
|
|
301
304
|
try {
|
|
302
|
-
return await
|
|
305
|
+
return await loadPromise;
|
|
303
306
|
} finally{
|
|
304
307
|
mfInstanceLoadingCache.delete(cacheKey);
|
|
305
308
|
}
|
|
@@ -421,15 +424,55 @@ function buildFinalUrls(pkg, version, localFallback) {
|
|
|
421
424
|
if (localFallback) urls.push(localFallback);
|
|
422
425
|
return urls;
|
|
423
426
|
}
|
|
424
|
-
|
|
427
|
+
function dedupeRemotes(remotes) {
|
|
428
|
+
const map = new Map();
|
|
429
|
+
for (const remote of remotes){
|
|
430
|
+
if (!remote?.name) continue;
|
|
431
|
+
const key = [
|
|
432
|
+
remote.name,
|
|
433
|
+
'entry' in remote ? remote.entry || '' : '',
|
|
434
|
+
'version' in remote ? remote.version || '' : '',
|
|
435
|
+
remote.alias || ''
|
|
436
|
+
].join('::');
|
|
437
|
+
if (!map.has(key)) map.set(key, remote);
|
|
438
|
+
}
|
|
439
|
+
return Array.from(map.values());
|
|
440
|
+
}
|
|
441
|
+
async function resolveRegisteredRemotes(context, baseRemotes, remoteSourcePlugins) {
|
|
442
|
+
const remoteList = [
|
|
443
|
+
...baseRemotes
|
|
444
|
+
];
|
|
445
|
+
for (const plugin of remoteSourcePlugins)if (plugin.registerRemotes) try {
|
|
446
|
+
const pluginRemotes = await plugin.registerRemotes(context);
|
|
447
|
+
if (pluginRemotes?.length) remoteList.push(...pluginRemotes);
|
|
448
|
+
} catch (error) {
|
|
449
|
+
throw new Error(`[MF] remote 来源插件 ${plugin.name} 执行失败: ${error.message}`);
|
|
450
|
+
}
|
|
451
|
+
return dedupeRemotes(remoteList).filter((remote)=>!(remote.name === context.scopeName && 'entry' in remote && remote.entry === context.currentEntry));
|
|
452
|
+
}
|
|
453
|
+
function createRemoteSourcePlugin(name, remotes) {
|
|
454
|
+
return {
|
|
455
|
+
name,
|
|
456
|
+
registerRemotes: ()=>remotes
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
async function loadRemoteMultiVersion(options, plugins = [], extraOptions = {}) {
|
|
425
460
|
const { name, pkg, version = 'latest', retries = 3, delay = 1000, localFallback, cacheTTL = 86400000, revalidate = true, shared: customShared } = options;
|
|
461
|
+
const { remoteSourcePlugins = [], baseRemotes = [], registerOptions = {} } = extraOptions;
|
|
426
462
|
const finalVersion = await resolveFinalVersion(pkg, version, cacheTTL, revalidate);
|
|
427
463
|
const scopeName = `${name}`;
|
|
428
464
|
const urls = buildFinalUrls(pkg, finalVersion, localFallback);
|
|
429
465
|
const finalSharedConfig = getFinalSharedConfig(customShared);
|
|
430
|
-
console.log(finalSharedConfig, 'finalSharedConfig');
|
|
431
466
|
for (const url of urls)try {
|
|
432
|
-
|
|
467
|
+
const registeredRemotes = await resolveRegisteredRemotes({
|
|
468
|
+
options,
|
|
469
|
+
scopeName,
|
|
470
|
+
pkg,
|
|
471
|
+
finalVersion,
|
|
472
|
+
currentEntry: url,
|
|
473
|
+
allEntries: urls
|
|
474
|
+
}, baseRemotes, remoteSourcePlugins);
|
|
475
|
+
return await tryLoadRemote(scopeName, url, retries, delay, finalSharedConfig, plugins, registeredRemotes, registerOptions);
|
|
433
476
|
} catch (e) {
|
|
434
477
|
console.warn(`[MF] 切换 CDN 路径:${url} 失败,尝试下一个...`, e);
|
|
435
478
|
}
|
|
@@ -821,4 +864,4 @@ const eventBus = EventBusClass.create();
|
|
|
821
864
|
function createEventBus() {
|
|
822
865
|
return EventBusClass.create();
|
|
823
866
|
}
|
|
824
|
-
export { buildCdnUrls, buildFinalUrls, cancelPreload, checkModuleLoadable, checkRemoteHealth, checkVersionCompatibility, clearPreloadCache, compareVersions, createEventBus, eventBus, extractMajorVersion, fallbackPlugin, fetchAvailableVersions, fetchLatestVersion, findCompatibleVersion, formatHealthStatus, getCompatibleReactVersions, getFinalSharedConfig, getLatestVersion, getLoadedRemotes, getPreloadStatus, getRemoteHealthReport, getStableVersions, getVersionCache, isPrerelease, isRemoteLoaded, loadReactVersion, loadRemoteMultiVersion, parseVersion, preloadRemote, preloadRemoteList, registerLoadedModule, registerRemoteInstance, resolveFinalVersion, satisfiesVersion, setVersionCache, sortVersions, tryLoadRemote, unloadAll, unloadRemote };
|
|
867
|
+
export { buildCdnUrls, buildFinalUrls, cancelPreload, checkModuleLoadable, checkRemoteHealth, checkVersionCompatibility, clearPreloadCache, compareVersions, createEventBus, createRemoteSourcePlugin, eventBus, extractMajorVersion, fallbackPlugin, fetchAvailableVersions, fetchLatestVersion, findCompatibleVersion, formatHealthStatus, getCompatibleReactVersions, getFinalSharedConfig, getLatestVersion, getLoadedRemotes, getPreloadStatus, getRemoteHealthReport, getStableVersions, getVersionCache, isPrerelease, isRemoteLoaded, loadReactVersion, loadRemoteMultiVersion, parseVersion, preloadRemote, preloadRemoteList, registerLoadedModule, registerRemoteInstance, resolveFinalVersion, satisfiesVersion, setVersionCache, sortVersions, tryLoadRemote, unloadAll, unloadRemote };
|
package/dist/types/index.d.ts
CHANGED
package/loadRemote.md
CHANGED
|
@@ -168,7 +168,8 @@ async function loadMultipleComponents() {
|
|
|
168
168
|
```typescript
|
|
169
169
|
function loadRemoteMultiVersion(
|
|
170
170
|
options: LoadRemoteOptions,
|
|
171
|
-
plugins
|
|
171
|
+
plugins?: ModuleFederationRuntimePlugin[],
|
|
172
|
+
extraOptions?: LoadRemoteExtraOptions,
|
|
172
173
|
): Promise<LoadResult>
|
|
173
174
|
```
|
|
174
175
|
|
|
@@ -192,6 +193,14 @@ function loadRemoteMultiVersion(
|
|
|
192
193
|
|
|
193
194
|
Module Federation 运行时插件数组,默认会添加 `fallbackPlugin()`。
|
|
194
195
|
|
|
196
|
+
**extraOptions**: `LoadRemoteExtraOptions`
|
|
197
|
+
|
|
198
|
+
| 属性 | 类型 | 必填 | 默认值 | 描述 |
|
|
199
|
+
|------|------|------|--------|------|
|
|
200
|
+
| `baseRemotes` | `RuntimeRemote[]` | ❌ | `[]` | 直接注册的附加 remote 列表 |
|
|
201
|
+
| `remoteSourcePlugins` | `RemoteSourcePlugin[]` | ❌ | `[]` | 通过插件动态返回并注册 remote 列表 |
|
|
202
|
+
| `registerOptions` | `{ force?: boolean }` | ❌ | `{}` | 透传给 `registerRemotes` 的配置 |
|
|
203
|
+
|
|
195
204
|
#### 返回值
|
|
196
205
|
|
|
197
206
|
```typescript
|
|
@@ -869,6 +878,38 @@ const { mf } = await loadRemoteMultiVersion(options, [
|
|
|
869
878
|
]);
|
|
870
879
|
```
|
|
871
880
|
|
|
881
|
+
#### 4. 通过 `registerRemotes` 动态注册多个来源
|
|
882
|
+
|
|
883
|
+
```typescript
|
|
884
|
+
import { loadRemoteMultiVersion, createRemoteSourcePlugin } from 'remote-reload-utils';
|
|
885
|
+
|
|
886
|
+
const remoteSourcePlugin = createRemoteSourcePlugin('multi-remote-source', [
|
|
887
|
+
{
|
|
888
|
+
name: 'remote_ui_v2',
|
|
889
|
+
entry: 'https://cdn.example.com/remote-ui-v2/dist/remoteEntry.js',
|
|
890
|
+
},
|
|
891
|
+
{
|
|
892
|
+
name: 'remote_widget',
|
|
893
|
+
entry: 'https://cdn.example.com/remote-widget/dist/remoteEntry.js',
|
|
894
|
+
},
|
|
895
|
+
]);
|
|
896
|
+
|
|
897
|
+
const { scopeName, mf } = await loadRemoteMultiVersion(
|
|
898
|
+
{
|
|
899
|
+
name: 'react_mf_lib',
|
|
900
|
+
pkg: 'test-mf-unpkg',
|
|
901
|
+
version: 'latest',
|
|
902
|
+
},
|
|
903
|
+
[],
|
|
904
|
+
{
|
|
905
|
+
remoteSourcePlugins: [remoteSourcePlugin],
|
|
906
|
+
},
|
|
907
|
+
);
|
|
908
|
+
|
|
909
|
+
const Button = await mf.loadRemote(`${scopeName}/Button`);
|
|
910
|
+
const Widget = await mf.loadRemote('remote_widget/Widget');
|
|
911
|
+
```
|
|
912
|
+
|
|
872
913
|
#### 2. 监控加载状态
|
|
873
914
|
|
|
874
915
|
```typescript
|
|
@@ -1238,7 +1279,31 @@ interface LoadRemoteOptions {
|
|
|
1238
1279
|
localFallback?: string; // 本地兜底
|
|
1239
1280
|
cacheTTL?: number; // 缓存时间
|
|
1240
1281
|
revalidate?: boolean; // 灰度更新
|
|
1241
|
-
shared?: Record<string,
|
|
1282
|
+
shared?: Record<string, any>; // 自定义 shared 配置
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
interface LoadRemoteExtraOptions {
|
|
1286
|
+
remoteSourcePlugins?: RemoteSourcePlugin[];
|
|
1287
|
+
baseRemotes?: RuntimeRemote[];
|
|
1288
|
+
registerOptions?: {
|
|
1289
|
+
force?: boolean;
|
|
1290
|
+
};
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
interface RemoteSourcePluginContext {
|
|
1294
|
+
options: LoadRemoteOptions;
|
|
1295
|
+
scopeName: string;
|
|
1296
|
+
pkg: string;
|
|
1297
|
+
finalVersion: string;
|
|
1298
|
+
currentEntry: string;
|
|
1299
|
+
allEntries: string[];
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
interface RemoteSourcePlugin {
|
|
1303
|
+
name: string;
|
|
1304
|
+
registerRemotes?: (
|
|
1305
|
+
context: RemoteSourcePluginContext
|
|
1306
|
+
) => RuntimeRemote[] | void | Promise<RuntimeRemote[] | void>;
|
|
1242
1307
|
}
|
|
1243
1308
|
|
|
1244
1309
|
interface VersionCache {
|