import React from 'react'; import { getInstance, type FederationHost, } from '@module-federation/enhanced/runtime'; import { ErrorBoundary, ErrorBoundaryPropsWithComponent, } from 'react-error-boundary'; type IProps = { id: string; injectScript?: boolean; injectLink?: boolean; }; type ReactKey = { key?: React.Key | null }; function getLoadedRemoteInfos(instance: FederationHost, id: string) { const { name, expose } = instance.remoteHandler.idToRemoteMap[id] || {}; if (!name) { return; } const module = instance.moduleCache.get(name); if (!module) { return; } const { remoteSnapshot } = instance.snapshotHandler.getGlobalRemoteInfo( module.remoteInfo, ); return { ...module.remoteInfo, snapshot: remoteSnapshot, expose, }; } function getTargetModuleInfo(id: string) { const instance = getInstance(); if (!instance) { return; } const loadedRemoteInfo = getLoadedRemoteInfos(instance, id); if (!loadedRemoteInfo) { return; } const snapshot = loadedRemoteInfo.snapshot; if (!snapshot) { return; } const publicPath = 'publicPath' in snapshot ? snapshot.publicPath : 'getPublicPath' in snapshot ? new Function(snapshot.getPublicPath)() : ''; if (!publicPath) { return; } const modules = 'modules' in snapshot ? snapshot.modules : []; const targetModule = modules.find( (m) => m.modulePath === loadedRemoteInfo.expose, ); if (!targetModule) { return; } const remoteEntry = 'remoteEntry' in snapshot ? snapshot.remoteEntry : ''; if (!remoteEntry) { return; } return { module: targetModule, publicPath, remoteEntry, }; } export function collectSSRAssets(options: IProps) { const { id, injectLink = true, injectScript = true, } = typeof options === 'string' ? { id: options } : options; const links: React.ReactNode[] = []; const scripts: React.ReactNode[] = []; const instance = getInstance(); if (!instance || (!injectLink && !injectScript)) { return [...scripts, ...links]; } const moduleAndPublicPath = getTargetModuleInfo(id); if (!moduleAndPublicPath) { return [...scripts, ...links]; } const { module: targetModule, publicPath, remoteEntry } = moduleAndPublicPath; if (injectLink) { [...targetModule.assets.css.sync, ...targetModule.assets.css.async].forEach( (file, index) => { links.push( , ); }, ); } if (injectScript) { scripts.push(