Skip to content

Commit 01d2125

Browse files
refactor dynamic remote example (#3849)
Co-authored-by: ScriptedAlchemy <[email protected]>
1 parent e6b24fc commit 01d2125

File tree

1 file changed

+20
-85
lines changed
  • advanced-api/dynamic-remotes/app1/src

1 file changed

+20
-85
lines changed

advanced-api/dynamic-remotes/app1/src/App.js

Lines changed: 20 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import React from 'react';
1+
import React, { useState, useEffect, Suspense } from 'react';
2+
23
import { init,loadRemote } from '@module-federation/runtime'
34

45
init({
@@ -16,104 +17,40 @@ init({
1617
})
1718

1819

19-
function loadComponent(scope, module) {
20-
return async () => {
21-
// Initializes the share scope. This fills it with known provided modules from this build and all remotes
22-
const Module = await loadRemote(`${scope}/${module.slice(2)}`);
23-
return Module;
24-
};
25-
}
26-
27-
const urlCache = new Set();
28-
const useDynamicScript = url => {
29-
const [ready, setReady] = React.useState(false);
30-
const [errorLoading, setErrorLoading] = React.useState(false);
31-
32-
React.useEffect(() => {
33-
if (!url) return;
34-
35-
if (urlCache.has(url)) {
36-
setReady(true);
37-
setErrorLoading(false);
38-
return;
39-
}
40-
41-
setReady(false);
42-
setErrorLoading(false);
43-
44-
const element = document.createElement('script');
45-
46-
element.src = url;
47-
element.type = 'text/javascript';
48-
element.async = true;
49-
50-
element.onload = () => {
51-
urlCache.add(url);
52-
setReady(true);
53-
};
20+
function useDynamicImport({module,scope}) {
21+
console.log(module,scope)
22+
const [component, setComponent] = useState(null);
5423

55-
element.onerror = () => {
56-
setReady(false);
57-
setErrorLoading(true);
24+
useEffect(() => {
25+
if(!module && !scope) return
26+
const loadComponent = async () => {
27+
const { default: component } = await loadRemote(`${scope}/${module}`);
28+
setComponent(() => component);
5829
};
59-
60-
document.head.appendChild(element);
61-
62-
return () => {
63-
urlCache.delete(url);
64-
document.head.removeChild(element);
65-
};
66-
}, [url]);
67-
68-
return {
69-
errorLoading,
70-
ready,
71-
};
72-
};
73-
74-
const componentCache = new Map();
75-
export const useFederatedComponent = (remoteUrl, scope, module) => {
76-
const key = `${remoteUrl}-${scope}-${module}`;
77-
const [Component, setComponent] = React.useState(null);
78-
79-
const { ready, errorLoading } = useDynamicScript(remoteUrl);
80-
React.useEffect(() => {
81-
if (Component) setComponent(null);
82-
// Only recalculate when key changes
83-
}, [key]);
84-
85-
React.useEffect(() => {
86-
if (ready && !Component) {
87-
const Comp = React.lazy(loadComponent(scope, module));
88-
componentCache.set(key, Comp);
89-
setComponent(Comp);
90-
}
91-
// key includes all dependencies (scope/module)
92-
}, [Component, ready, key]);
93-
94-
return { errorLoading, Component };
95-
};
30+
loadComponent();
31+
}, [module,scope]);
32+
const fallback = ()=> null
33+
return component || fallback
34+
}
9635

9736
function App() {
98-
const [{ module, scope, url }, setSystem] = React.useState({});
37+
const [{ module, scope }, setSystem] = React.useState({});
9938

10039
function setApp2() {
10140
setSystem({
102-
url: 'http://localhost:3002/remoteEntry.js',
10341
scope: 'app2',
104-
module: './Widget',
42+
module: 'Widget',
10543
});
10644
}
10745

10846
function setApp3() {
10947
setSystem({
110-
url: 'http://localhost:3003/remoteEntry.js',
11148
scope: 'app3',
112-
module: './Widget',
49+
module: 'Widget',
11350
});
11451
}
11552

116-
const { Component: FederatedComponent, errorLoading } = useFederatedComponent(url, scope, module);
53+
const Component = useDynamicImport({module,scope});
11754

11855
return (
11956
<div
@@ -132,9 +69,7 @@ function App() {
13269
<button onClick={setApp3}>Load App 3 Widget</button>
13370
<div style={{ marginTop: '2em' }}>
13471
<React.Suspense fallback="Loading System">
135-
{errorLoading
136-
? `Error loading module "${module}"`
137-
: FederatedComponent && <FederatedComponent />}
72+
<Component />
13873
</React.Suspense>
13974
</div>
14075
</div>

0 commit comments

Comments
 (0)