From bf55441a6deac6ce30c4c85bf51bca6bb63aea87 Mon Sep 17 00:00:00 2001 From: Dmitrii Derepko Date: Fri, 28 Jul 2023 18:34:41 +0300 Subject: [PATCH 1/2] Enable shared page --- packages/yii-dev-panel-sdk/src/Pages/Layout.tsx | 2 +- packages/yii-dev-panel/src/Application/Pages/SharedPage.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/yii-dev-panel-sdk/src/Pages/Layout.tsx b/packages/yii-dev-panel-sdk/src/Pages/Layout.tsx index e9427855..21929038 100644 --- a/packages/yii-dev-panel-sdk/src/Pages/Layout.tsx +++ b/packages/yii-dev-panel-sdk/src/Pages/Layout.tsx @@ -52,7 +52,7 @@ const pages = [ }, {name: 'Open API', link: '/open-api'}, // Uncomment to debug shared components - // {name: 'Shared', link: '/shared'}, + {name: 'Shared', link: '/shared'}, ]; const StyledLink = styled(Link)(({theme}) => { return { diff --git a/packages/yii-dev-panel/src/Application/Pages/SharedPage.tsx b/packages/yii-dev-panel/src/Application/Pages/SharedPage.tsx index 88e00d18..0abd7818 100644 --- a/packages/yii-dev-panel/src/Application/Pages/SharedPage.tsx +++ b/packages/yii-dev-panel/src/Application/Pages/SharedPage.tsx @@ -33,7 +33,7 @@ export function SharedPage() { return ( }> Date: Fri, 28 Jul 2023 18:38:34 +0300 Subject: [PATCH 2/2] Replace webpack loader with vite one --- .../src/Application/Pages/RemoteComponent.tsx | 142 ++++++++---------- 1 file changed, 59 insertions(+), 83 deletions(-) diff --git a/packages/yii-dev-panel/src/Application/Pages/RemoteComponent.tsx b/packages/yii-dev-panel/src/Application/Pages/RemoteComponent.tsx index c6e801aa..9ba8aeef 100644 --- a/packages/yii-dev-panel/src/Application/Pages/RemoteComponent.tsx +++ b/packages/yii-dev-panel/src/Application/Pages/RemoteComponent.tsx @@ -1,103 +1,79 @@ import {Alert} from '@mui/material'; -import {FullScreenCircularProgress} from '@yiisoft/yii-dev-panel-sdk/Component/FullScreenCircularProgress'; -import React, {Suspense} from 'react'; - -type UseDynamicScriptProps = { - url: string | undefined; +import {lazy, Suspense} from 'react'; +import {ErrorBoundary} from 'react-error-boundary'; + +const remotesMap = {}; +// const __vite__import = name => import(/* @vite-ignore */name); + +const shareScope = { + // 'react': { + // 'default': { + // get: () => __vite__import('http://localhost:5001/assets/__federation_shared_react.js'), + // loaded: 1 + // } + // }, + // 'react-dom': { + // 'default': { + // get: () => __vite__import('http://localhost:5001/assets/__federation_shared_react-dom.js'), + // loaded: 1 + // } + // }, }; -const useDynamicScript = ({url}: UseDynamicScriptProps) => { - const [ready, setReady] = React.useState(false); - const [failed, setFailed] = React.useState(false); - React.useEffect(() => { - if (!url) { - return; +if (!globalThis.__federation_shared__) { + globalThis.__federation_shared__ = shareScope; +} +var __federation__ = { + ensure: async (remoteId) => { + const remote = remotesMap[remoteId]; + if (remote.inited) { + return remote.lib; } - - const element = document.createElement('script'); - - element.src = url; - element.type = 'text/javascript'; - element.async = true; - - setReady(false); - setFailed(false); - - element.onload = () => { - console.debug(`Dynamic Script Loaded: ${url}`); - setReady(true); - }; - - element.onerror = () => { - console.error(`Dynamic Script Error: ${url}`); - setReady(false); - setFailed(true); - }; - - document.head.appendChild(element); - - return () => { - console.debug(`Dynamic Script Unloaded: ${url}`); - document.head.removeChild(element); - }; - }, [url]); - - return { - ready, - failed, - }; -}; - -const loadComponent = (scope: string, module: string) => async () => { - /** - * Initializes the shared scope. This fills it with known provided modules from this build and all remotes - */ - // @ts-ignore - await __webpack_init_sharing__('default'); - // @ts-ignore - const container = window[scope]; - /** - * Initialize the container, it may provide shared modules - */ - // @ts-ignore - await container.init(__webpack_share_scopes__.default); - // @ts-ignore - const factory = await window[scope].get(module); - const Module = factory(); - return Module; + return new Promise((resolve) => { + // debugger; + import(/* @vite-ignore */ remote.url).then((lib) => { + debugger; + console.log('lib', lib); + if (!remote.inited) { + lib.init(globalThis.__federation_shared__); + remote.lib = lib; + remote.inited = true; + } + resolve(remote.lib); + }); + }); + }, }; +const loadComponent = (url, scope, module) => async () => { + remotesMap[scope] = { + url: url, + }; -type ModuleLoaderProps = { - module: string; - url: string; - scope: string; - props: any; + return __federation__.ensure(scope).then((remote) => remote.get(module).then((factory) => factory())); }; -const ModuleLoader = ({module, props, scope, url}: ModuleLoaderProps) => { - const dynamicScript = useDynamicScript({ - url: module && url, - }); - +const ModuleLoader = ({module, props, scope, url}) => { if (!module) { return Module name cannot be empty; } - if (!dynamicScript.ready) { - return ; - } - - if (dynamicScript.failed) { - return Failed to load dynamic script: {url}; - } - - const Component = React.lazy(loadComponent(scope, module)); + const Component = lazy(loadComponent(url, scope, module)); return ( - }> + Loading...}> ); }; +export const RemoteButton = () => { + const url = 'http://localhost:5001/assets/remoteEntry.js'; + + return ( + Failed to load remote component...}> + + + ); +}; + export default ModuleLoader;