@@ -172,7 +172,7 @@ The `lifecycle` parameter indicates the stage where the error occurred:
172172- ` afterResolve ` : Error during manifest loading (most common for network failures)
173173- ` onLoad ` : Error during module loading and execution
174174- ` beforeLoadShare ` : Error during shared dependency loading
175-
175+
176176* example
177177
178178` ` ` ts
@@ -185,12 +185,12 @@ const fallbackPlugin: () => ModuleFederationRuntimePlugin =
185185 name: ' fallback-plugin' ,
186186 errorLoadRemote(args ) {
187187 const { lifecycle, id, error } = args ;
188-
188+
189189 // Log error details safely
190190 if (error ) {
191191 console .warn (` Failed to load remote ${id } at ${lifecycle }: ` , error ?.message || error );
192192 }
193-
193+
194194 // Handle different error types based on lifecycle
195195 switch (lifecycle ) {
196196 case ' afterResolve' :
@@ -203,27 +203,27 @@ const fallbackPlugin: () => ModuleFederationRuntimePlugin =
203203 remotes: [],
204204 exposes: []
205205 };
206-
206+
207207 case ' beforeRequest' :
208208 // Request processing failed - can return modified args or void
209209 console .warn (` Request processing failed for ${id } ` );
210210 return void 0 ;
211-
211+
212212 case ' onLoad' :
213213 // Module loading failed - provide fallback component
214214 return () => ({
215215 __esModule: true ,
216216 default : () => ' Fallback Component'
217217 });
218-
218+
219219 case ' beforeLoadShare' :
220220 // Shared dependency loading failed - return fallback shared module
221221 console .warn (` Shared dependency loading failed for ${id } ` );
222222 return () => ({
223223 __esModule: true ,
224224 default: {}
225225 });
226-
226+
227227 default :
228228 // Unknown lifecycle - log and return void
229229 console .warn (` Unknown lifecycle ${lifecycle } for ${id } ` );
@@ -425,3 +425,167 @@ const changeScriptAttributePlugin: () => ModuleFederationRuntimePlugin =
425425 };
426426 };
427427```
428+
429+ ## fetch
430+ The ` fetch ` function allows customizing the request that fetches the manifest JSON. A successful ` Response ` must yield a valid JSON.
431+
432+ ` AsyncHook `
433+
434+ - ** Type**
435+
436+ ``` typescript
437+ function fetch(manifestUrl : string , requestInit : RequestInit ): Promise <Response > | void | false ;
438+ ```
439+
440+ - Example for including the credentials when fetching the manifest JSON:
441+
442+ ``` typescript
443+ // fetch-manifest-with-credentials-plugin.ts
444+ import type { FederationRuntimePlugin } from ' @module-federation/enhanced/runtime' ;
445+
446+ export default function (): FederationRuntimePlugin {
447+ return {
448+ name: ' fetch-manifest-with-credentials-plugin' ,
449+ fetch(manifestUrl , requestInit ) {
450+ return fetch (manifestUrl , {
451+ ... requestInit ,
452+ credentials: ' include'
453+ });
454+ },
455+ }
456+ };
457+ ```
458+
459+ ## loadEntry
460+ The ` loadEntry ` function allows for full customization of remotes, enabling you to extend and create new remote types. The following two simple examples demonstrate loading JSON data and module delegation.
461+
462+ ` asyncHook `
463+
464+ - ** Type**
465+
466+ ``` typescript
467+ function loadEntry(args : LoadEntryOptions ): RemoteEntryExports | void ;
468+
469+ type LoadEntryOptions = {
470+ createScriptHook: SyncHook ,
471+ remoteEntryExports? : RemoteEntryExports ,
472+ remoteInfo: RemoteInfo
473+ };
474+ interface RemoteInfo {
475+ name: string ;
476+ version? : string ;
477+ buildVersion? : string ;
478+ entry: string ;
479+ type: RemoteEntryType ;
480+ entryGlobalName: string ;
481+ shareScope: string ;
482+ }
483+ export type RemoteEntryExports = {
484+ get: (id : string ) => () => Promise <Module >;
485+ init: (
486+ shareScope : ShareScopeMap [string ],
487+ initScope ? : InitScope ,
488+ remoteEntryInitOPtions ? : RemoteEntryInitOptions ,
489+ ) => void | Promise <void >;
490+ };
491+ ```
492+
493+ - Example Loading JSON Data
494+
495+ ``` typescript
496+ // load-json-data-plugin.ts
497+ import { init } from ' @module-federation/enhanced/runtime' ;
498+ import type { FederationRuntimePlugin } from ' @module-federation/enhanced/runtime' ;
499+
500+ const changeScriptAttributePlugin: () => FederationRuntimePlugin = function () {
501+ return {
502+ name: ' load-json-data-plugin' ,
503+ loadEntry({ remoteInfo }) {
504+ if (remoteInfo .jsonA === " jsonA" ) {
505+ return {
506+ init(shareScope , initScope , remoteEntryInitOPtions ) {},
507+ async get(path ) {
508+ const json = await fetch (remoteInfo .entry + " .json" ).then (res => res .json ())
509+ return () => ({
510+ path ,
511+ json
512+ })
513+ }
514+ }
515+ }
516+ },
517+ };
518+ };
519+ ```
520+ ``` ts
521+ // module-federation-config
522+ {
523+ remotes : {
524+ jsonA : " jsonA@https://cdn.jsdelivr.net/npm/@module-federation/runtime/package"
525+ }
526+ }
527+ ```
528+ ``` ts
529+ // src/bootstrap.js
530+ import jsonA from " jsonA"
531+ jsonA // {...json data}
532+ ```
533+
534+ - Example Delegate Modules
535+
536+ ``` typescript
537+ // delegate-modules-plugin.ts
538+ import { init } from ' @module-federation/enhanced/runtime' ;
539+ import type { FederationRuntimePlugin } from ' @module-federation/enhanced/runtime' ;
540+
541+ const changeScriptAttributePlugin: () => FederationRuntimePlugin = function () {
542+ return {
543+ name: ' delegate-modules-plugin' ,
544+ loadEntry({ remoteInfo }) {
545+ if (remoteInfo .name === " delegateModulesA" ) {
546+ return {
547+ init(shareScope , initScope , remoteEntryInitOPtions ) {},
548+ async get(path ) {
549+ path = path .replace (" ./" , " " )
550+ const {[path ]: factory} = await import (" ./delegateModulesA.js" )
551+ const result = await factory ()
552+ return () => result
553+ }
554+ }
555+ }
556+ },
557+ };
558+ };
559+ ```
560+ ``` ts
561+ // ./src/delegateModulesA.js
562+ export async function test1() {
563+ return new Promise (resolve => {
564+ setTimeout (() => {
565+ resolve (" test1 value" )
566+ }, 3000 )
567+ })
568+ }
569+ export async function test2() {
570+ return new Promise (resolve => {
571+ setTimeout (() => {
572+ resolve (" test2 value" )
573+ }, 3000 )
574+ })
575+ }
576+ ```
577+ ``` ts
578+ // module-federation-config
579+ {
580+ remotes : {
581+ delegateModulesA : " delegateModulesA@https://delegateModulesA.js"
582+ }
583+ }
584+ ```
585+ ``` ts
586+ // src/bootstrap.js
587+ import test1 from " delegateModulesA/test1"
588+ import test2 from " delegateModulesA/test2"
589+ test1 // "test1 value"
590+ test2 // "test2 value"
591+ ```
0 commit comments