-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
/
Copy pathindex.js
119 lines (102 loc) · 3.47 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
const React = require('react');
const createMatcher = require('feather-route-matcher');
const { loadRemote } = require('@module-federation/runtime');
async function matchFederatedPage(path) {
const remotes = new Set(
...__FEDERATION__.__INSTANCES__.map(item => {
return item.options.remotes.map(r => r.alias);
}),
);
const maps = await Promise.all(
Array.from(remotes).map(async remote => {
return loadRemote(remote + '/pages-map')
.then(factory => ({ remote, config: factory.default }))
.catch(() => null);
}),
);
const config = {};
for (const map of maps) {
if (!map) continue;
for (let [path, mod] of Object.entries(map.config)) {
config[path] = {
remote: map.remote,
module: mod,
};
}
}
const matcher = createMatcher.default(config);
return matcher(path);
}
module.exports = {
matchFederatedPage,
createFederatedCatchAll() {
const FederatedCatchAll = initialProps => {
const [lazyProps, setProps] = React.useState({});
const { FederatedPage, render404, renderError, needsReload, ...props } = {
...lazyProps,
...initialProps,
};
React.useEffect(() => {
if (needsReload) {
const runUnderlayingGIP = async () => {
const federatedProps = await FederatedCatchAll.getInitialProps(props);
setProps(federatedProps);
};
runUnderlayingGIP();
}
}, []);
if (render404) {
// TODO: Render 404 page
return React.createElement('h1', {}, '404 Not Found');
}
if (renderError) {
// TODO: Render error page
return React.createElement('h1', {}, 'Oops, something went wrong.');
}
if (FederatedPage) {
return React.createElement(FederatedPage, props);
}
return null;
};
FederatedCatchAll.getInitialProps = async ctx => {
// Bot marks "req, res, AppTree" as unused but those are vital to not get circular-dependency error
const { err, req, res, AppTree, ...props } = ctx;
if (err) {
// TODO: Run getInitialProps for error page
return { renderError: true, ...props };
}
if (!process.browser) {
return { needsReload: true, ...props };
}
console.log('in browser');
const matchedPage = await matchFederatedPage(ctx.asPath);
try {
console.log('matchedPage', matchedPage);
const remote = matchedPage?.value?.remote;
const mod = matchedPage?.value?.module.replace('./', '/');
if (!remote || !mod) {
// TODO: Run getInitialProps for 404 page
return { render404: true, ...props };
}
console.log('loading exposed module', mod, 'from remote', remote);
const FederatedPage = await loadRemote(remote + mod).then(factory => factory.default);
console.log('FederatedPage', FederatedPage);
if (!FederatedPage) {
// TODO: Run getInitialProps for 404 page
return { render404: true, ...props };
}
const modifiedContext = {
...ctx,
query: matchedPage.params,
};
const federatedPageProps = (await FederatedPage.getInitialProps?.(modifiedContext)) || {};
return { ...federatedPageProps, FederatedPage };
} catch (err) {
console.log('err', err);
// TODO: Run getInitialProps for error page
return { renderError: true, ...props };
}
};
return FederatedCatchAll;
},
};