@umijs/renderer-react 4.0.0-canary.20220614.2 → 4.0.0-canary.20220620.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/appContext.d.ts +11 -5
- package/dist/appContext.js +6 -1
- package/dist/browser.d.ts +2 -0
- package/dist/browser.js +33 -9
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/link.js +1 -1
- package/dist/routes.js +15 -5
- package/dist/server.d.ts +11 -0
- package/dist/server.js +59 -0
- package/dist/types.d.ts +1 -0
- package/dist/useFetcher.d.ts +3 -0
- package/dist/useFetcher.js +11 -0
- package/package.json +1 -1
package/dist/appContext.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { IClientRoute, ILoaderData, IRouteComponents, IRoutesById } from './types';
|
|
3
|
-
interface
|
|
3
|
+
interface IAppContextType {
|
|
4
4
|
routes: IRoutesById;
|
|
5
5
|
routeComponents: IRouteComponents;
|
|
6
6
|
clientRoutes: IClientRoute[];
|
|
@@ -8,9 +8,15 @@ interface IAppCentextType {
|
|
|
8
8
|
rootElement?: HTMLElement;
|
|
9
9
|
basename?: string;
|
|
10
10
|
clientLoaderData: ILoaderData;
|
|
11
|
-
preloadRoute
|
|
11
|
+
preloadRoute?: (to: string) => void;
|
|
12
|
+
serverLoaderData: ILoaderData;
|
|
12
13
|
}
|
|
13
|
-
export declare const AppContext: React.Context<
|
|
14
|
-
export declare function useAppData():
|
|
15
|
-
export declare function
|
|
14
|
+
export declare const AppContext: React.Context<IAppContextType>;
|
|
15
|
+
export declare function useAppData(): IAppContextType;
|
|
16
|
+
export declare function useServerLoaderData(): {
|
|
17
|
+
data: any;
|
|
18
|
+
};
|
|
19
|
+
export declare function useClientLoaderData(): {
|
|
20
|
+
data: any;
|
|
21
|
+
};
|
|
16
22
|
export {};
|
package/dist/appContext.js
CHANGED
|
@@ -4,8 +4,13 @@ export const AppContext = React.createContext({});
|
|
|
4
4
|
export function useAppData() {
|
|
5
5
|
return React.useContext(AppContext);
|
|
6
6
|
}
|
|
7
|
+
export function useServerLoaderData() {
|
|
8
|
+
const route = useRouteData();
|
|
9
|
+
const appData = useAppData();
|
|
10
|
+
return { data: appData.serverLoaderData[route.route.id] };
|
|
11
|
+
}
|
|
7
12
|
export function useClientLoaderData() {
|
|
8
13
|
const route = useRouteData();
|
|
9
14
|
const appData = useAppData();
|
|
10
|
-
return appData.clientLoaderData[route.route.id];
|
|
15
|
+
return { data: appData.clientLoaderData[route.route.id] };
|
|
11
16
|
}
|
package/dist/browser.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { History } from 'history';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { IRouteComponents, IRoutesById } from './types';
|
|
4
|
+
export declare function Routes(): React.ReactElement<any, string | React.JSXElementConstructor<any>> | null;
|
|
4
5
|
export declare function renderClient(opts: {
|
|
5
6
|
publicPath?: string;
|
|
6
7
|
runtimePublicPath?: boolean;
|
|
@@ -11,4 +12,5 @@ export declare function renderClient(opts: {
|
|
|
11
12
|
basename?: string;
|
|
12
13
|
loadingComponent?: React.ReactNode;
|
|
13
14
|
history: History;
|
|
15
|
+
hydrate?: boolean;
|
|
14
16
|
}): void;
|
package/dist/browser.js
CHANGED
|
@@ -29,7 +29,7 @@ function BrowserRoutes(props) {
|
|
|
29
29
|
}, [history, props.routes, props.clientRoutes]);
|
|
30
30
|
return (React.createElement(Router, { navigator: history, location: state.location, basename: props.basename }, props.children));
|
|
31
31
|
}
|
|
32
|
-
function Routes() {
|
|
32
|
+
export function Routes() {
|
|
33
33
|
const { clientRoutes } = useAppData();
|
|
34
34
|
return useRoutes(clientRoutes);
|
|
35
35
|
}
|
|
@@ -68,13 +68,17 @@ export function renderClient(opts) {
|
|
|
68
68
|
}
|
|
69
69
|
const Browser = () => {
|
|
70
70
|
const [clientLoaderData, setClientLoaderData] = useState({});
|
|
71
|
-
const
|
|
71
|
+
const [serverLoaderData, setServerLoaderData] = useState(
|
|
72
|
+
// @ts-ignore
|
|
73
|
+
window.__UMI_LOADER_DATA__ || {});
|
|
74
|
+
const handleRouteChange = useCallback((id, isFirst) => {
|
|
72
75
|
var _a;
|
|
73
76
|
// Patched routes has to id
|
|
74
|
-
const matchedRouteIds = (((_a = matchRoutes(clientRoutes,
|
|
77
|
+
const matchedRouteIds = (((_a = matchRoutes(clientRoutes, id)) === null || _a === void 0 ? void 0 : _a.map(
|
|
75
78
|
// @ts-ignore
|
|
76
79
|
(route) => route.route.id)) || []).filter(Boolean);
|
|
77
80
|
matchedRouteIds.forEach((id) => {
|
|
81
|
+
var _a;
|
|
78
82
|
// preload
|
|
79
83
|
// @ts-ignore
|
|
80
84
|
const manifest = window.__umi_manifest__;
|
|
@@ -101,8 +105,22 @@ export function renderClient(opts) {
|
|
|
101
105
|
document.head.appendChild(link);
|
|
102
106
|
}
|
|
103
107
|
}
|
|
108
|
+
// server loader
|
|
109
|
+
if (!isFirst && opts.routes[id].hasServerLoader) {
|
|
110
|
+
fetch('/__serverLoader?route=' + id)
|
|
111
|
+
.then((d) => d.json())
|
|
112
|
+
.then((data) => {
|
|
113
|
+
// setServerLoaderData when startTransition because if ssr is enabled,
|
|
114
|
+
// the component may being hydrated and setLoaderData will break the hydration
|
|
115
|
+
React.startTransition(() => {
|
|
116
|
+
setServerLoaderData((d) => ({ ...d, [id]: data }));
|
|
117
|
+
});
|
|
118
|
+
})
|
|
119
|
+
.catch(console.error);
|
|
120
|
+
}
|
|
104
121
|
// client loader
|
|
105
|
-
|
|
122
|
+
// onPatchClientRoutes 添加的 route 在 opts.routes 里是不存在的
|
|
123
|
+
const clientLoader = (_a = opts.routes[id]) === null || _a === void 0 ? void 0 : _a.clientLoader;
|
|
106
124
|
if (clientLoader && !clientLoaderData[id]) {
|
|
107
125
|
clientLoader().then((data) => {
|
|
108
126
|
setClientLoaderData((d) => ({ ...d, [id]: data }));
|
|
@@ -111,7 +129,7 @@ export function renderClient(opts) {
|
|
|
111
129
|
});
|
|
112
130
|
}, [clientLoaderData]);
|
|
113
131
|
useEffect(() => {
|
|
114
|
-
handleRouteChange(window.location.pathname);
|
|
132
|
+
handleRouteChange(window.location.pathname, true);
|
|
115
133
|
return opts.history.listen((e) => {
|
|
116
134
|
handleRouteChange(e.location.pathname);
|
|
117
135
|
});
|
|
@@ -124,14 +142,20 @@ export function renderClient(opts) {
|
|
|
124
142
|
rootElement: opts.rootElement,
|
|
125
143
|
basename,
|
|
126
144
|
clientLoaderData,
|
|
145
|
+
serverLoaderData,
|
|
127
146
|
preloadRoute: handleRouteChange,
|
|
128
147
|
} }, rootContainer));
|
|
129
148
|
};
|
|
130
|
-
if (
|
|
131
|
-
ReactDOM.
|
|
149
|
+
if (opts.hydrate) {
|
|
150
|
+
ReactDOM.hydrateRoot(rootElement, React.createElement(Browser, null));
|
|
132
151
|
}
|
|
133
152
|
else {
|
|
134
|
-
|
|
135
|
-
|
|
153
|
+
if (ReactDOM.createRoot) {
|
|
154
|
+
ReactDOM.createRoot(rootElement).render(React.createElement(Browser, null));
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
// @ts-ignore
|
|
158
|
+
ReactDOM.render(React.createElement(Browser, null), rootElement);
|
|
159
|
+
}
|
|
136
160
|
}
|
|
137
161
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { createBrowserHistory, createHashHistory, createMemoryHistory, History, } from 'history';
|
|
2
2
|
export { createSearchParams, matchPath, matchRoutes, Navigate, NavLink, Outlet, resolvePath, useLocation, useMatch, useNavigate, useOutlet, useOutletContext, useParams, useResolvedPath, useRoutes, useSearchParams, } from 'react-router-dom';
|
|
3
|
-
export { useAppData, useClientLoaderData } from './appContext';
|
|
3
|
+
export { useAppData, useClientLoaderData, useServerLoaderData, } from './appContext';
|
|
4
4
|
export { renderClient } from './browser';
|
|
5
5
|
export { LinkWithPrefetch as Link } from './link';
|
|
6
6
|
export { useRouteData } from './routeContext';
|
|
7
|
+
export { __useFetcher } from './useFetcher';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { createBrowserHistory, createHashHistory, createMemoryHistory, } from 'history';
|
|
2
2
|
export { createSearchParams, matchPath, matchRoutes, Navigate, NavLink, Outlet, resolvePath, useLocation, useMatch, useNavigate, useOutlet, useOutletContext, useParams, useResolvedPath, useRoutes, useSearchParams, } from 'react-router-dom';
|
|
3
|
-
export { useAppData, useClientLoaderData } from './appContext';
|
|
3
|
+
export { useAppData, useClientLoaderData, useServerLoaderData, } from './appContext';
|
|
4
4
|
export { renderClient } from './browser';
|
|
5
5
|
export { LinkWithPrefetch as Link } from './link';
|
|
6
6
|
export { useRouteData } from './routeContext';
|
|
7
|
+
export { __useFetcher } from './useFetcher';
|
package/dist/link.js
CHANGED
|
@@ -4,5 +4,5 @@ import { useAppData } from './appContext';
|
|
|
4
4
|
export function LinkWithPrefetch(props) {
|
|
5
5
|
const appData = useAppData();
|
|
6
6
|
const to = typeof props.to === 'string' ? props.to : props.to.pathname;
|
|
7
|
-
return (React.createElement(Link, { onMouseEnter: () => props.prefetch && to && appData.preloadRoute(to), ...props }, props.children));
|
|
7
|
+
return (React.createElement(Link, { onMouseEnter: () => { var _a; return props.prefetch && to && ((_a = appData.preloadRoute) === null || _a === void 0 ? void 0 : _a.call(appData, to)); }, ...props }, props.children));
|
|
8
8
|
}
|
package/dist/routes.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
// @ts-ignore
|
|
2
|
-
import loadable from '@loadable/component';
|
|
3
2
|
import React from 'react';
|
|
4
3
|
import { Navigate } from 'react-router-dom';
|
|
5
4
|
import { RouteContext } from './routeContext';
|
|
@@ -43,8 +42,19 @@ function DefaultLoading() {
|
|
|
43
42
|
return React.createElement("div", null);
|
|
44
43
|
}
|
|
45
44
|
function RemoteComponent(props) {
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
const useSuspense = true; // !!React.startTransition;
|
|
46
|
+
if (useSuspense) {
|
|
47
|
+
const Component = props.loader;
|
|
48
|
+
return (React.createElement(React.Suspense, { fallback: React.createElement(props.loadingComponent, null) },
|
|
49
|
+
React.createElement(Component, null)));
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
return null;
|
|
53
|
+
// // @ts-ignore
|
|
54
|
+
// import loadable from '@loadable/component';
|
|
55
|
+
// const Component = loadable(props.loader, {
|
|
56
|
+
// fallback: <props.loadingComponent />,
|
|
57
|
+
// });
|
|
58
|
+
// return <Component />;
|
|
59
|
+
}
|
|
50
60
|
}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IRouteComponents, IRoutesById } from './types';
|
|
2
|
+
export declare function getClientRootComponent(opts: {
|
|
3
|
+
routes: IRoutesById;
|
|
4
|
+
routeComponents: IRouteComponents;
|
|
5
|
+
pluginManager: any;
|
|
6
|
+
location: string;
|
|
7
|
+
loaderData: {
|
|
8
|
+
[routeKey: string]: any;
|
|
9
|
+
};
|
|
10
|
+
manifest: any;
|
|
11
|
+
}): Promise<JSX.Element>;
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StaticRouter } from 'react-router-dom/server';
|
|
3
|
+
import { AppContext } from './appContext';
|
|
4
|
+
import { Routes } from './browser';
|
|
5
|
+
import { createClientRoutes } from './routes';
|
|
6
|
+
// Get the root React component for ReactDOMServer.renderToString
|
|
7
|
+
export async function getClientRootComponent(opts) {
|
|
8
|
+
const basename = '/';
|
|
9
|
+
const components = { ...opts.routeComponents };
|
|
10
|
+
const clientRoutes = createClientRoutes({
|
|
11
|
+
routesById: opts.routes,
|
|
12
|
+
routeComponents: components,
|
|
13
|
+
});
|
|
14
|
+
let rootContainer = (React.createElement(StaticRouter, { basename: basename, location: opts.location },
|
|
15
|
+
React.createElement(Routes, null)));
|
|
16
|
+
for (const key of [
|
|
17
|
+
// Lowest to the highest priority
|
|
18
|
+
'innerProvider',
|
|
19
|
+
'i18nProvider',
|
|
20
|
+
'accessProvider',
|
|
21
|
+
'dataflowProvider',
|
|
22
|
+
'outerProvider',
|
|
23
|
+
'rootContainer',
|
|
24
|
+
]) {
|
|
25
|
+
rootContainer = opts.pluginManager.applyPlugins({
|
|
26
|
+
type: 'modify',
|
|
27
|
+
key: key,
|
|
28
|
+
initialValue: rootContainer,
|
|
29
|
+
args: {},
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return (React.createElement(Html, { loaderData: opts.loaderData, manifest: opts.manifest },
|
|
33
|
+
React.createElement(AppContext.Provider, { value: {
|
|
34
|
+
routes: opts.routes,
|
|
35
|
+
routeComponents: opts.routeComponents,
|
|
36
|
+
clientRoutes,
|
|
37
|
+
pluginManager: opts.pluginManager,
|
|
38
|
+
basename,
|
|
39
|
+
clientLoaderData: {},
|
|
40
|
+
serverLoaderData: opts.loaderData,
|
|
41
|
+
} }, rootContainer)));
|
|
42
|
+
}
|
|
43
|
+
function Html({ children, loaderData, manifest }) {
|
|
44
|
+
// TODO: 处理 head 标签,比如 favicon.ico 的一致性
|
|
45
|
+
// TODO: root 支持配置
|
|
46
|
+
return (React.createElement("html", { lang: "en" },
|
|
47
|
+
React.createElement("head", null,
|
|
48
|
+
React.createElement("meta", { charSet: "utf-8" }),
|
|
49
|
+
React.createElement("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }),
|
|
50
|
+
manifest.assets['umi.css'] && (React.createElement("link", { rel: "stylesheet", href: manifest.assets['umi.css'] }))),
|
|
51
|
+
React.createElement("body", null,
|
|
52
|
+
React.createElement("noscript", { dangerouslySetInnerHTML: {
|
|
53
|
+
__html: `<b>Enable JavaScript to run this app.</b>`,
|
|
54
|
+
} }),
|
|
55
|
+
React.createElement("div", { id: "root" }, children),
|
|
56
|
+
React.createElement("script", { dangerouslySetInnerHTML: {
|
|
57
|
+
__html: `window.__UMI_LOADER_DATA__ = ${JSON.stringify(loaderData)}`,
|
|
58
|
+
} }))));
|
|
59
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { useLocation } from 'react-router-dom';
|
|
2
|
+
import { useAppData } from './appContext';
|
|
3
|
+
export function __useFetcher() {
|
|
4
|
+
const { preloadRoute } = useAppData();
|
|
5
|
+
const location = useLocation();
|
|
6
|
+
return {
|
|
7
|
+
load(path) {
|
|
8
|
+
preloadRoute(path || location.pathname);
|
|
9
|
+
},
|
|
10
|
+
};
|
|
11
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umijs/renderer-react",
|
|
3
|
-
"version": "4.0.0-canary.
|
|
3
|
+
"version": "4.0.0-canary.20220620.1",
|
|
4
4
|
"description": "@umijs/renderer-react",
|
|
5
5
|
"homepage": "https://github.com/umijs/umi-next/tree/master/packages/renderer-react#readme",
|
|
6
6
|
"bugs": "https://github.com/umijs/umi-next/issues",
|