@umijs/server 4.2.5 → 4.2.6-alpha.0
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/ssr.d.ts +19 -5
- package/dist/ssr.js +257 -74
- package/dist/types.d.ts +34 -0
- package/package.json +2 -2
package/dist/ssr.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
/// <reference lib="webworker" />
|
|
2
|
+
import type { RequestHandler } from '@umijs/bundler-utils/compiled/express';
|
|
1
3
|
import React from 'react';
|
|
2
|
-
import type { UmiRequest } from './types';
|
|
4
|
+
import type { IhtmlPageOpts, UmiRequest } from './types';
|
|
3
5
|
interface RouteLoaders {
|
|
4
6
|
[key: string]: () => Promise<any>;
|
|
5
7
|
}
|
|
@@ -12,22 +14,34 @@ interface CreateRequestServerlessOptions {
|
|
|
12
14
|
}
|
|
13
15
|
interface CreateRequestHandlerOptions extends CreateRequestServerlessOptions {
|
|
14
16
|
routesWithServerLoader: RouteLoaders;
|
|
15
|
-
|
|
17
|
+
pluginManager: any;
|
|
16
18
|
manifest: ((sourceDir?: string) => {
|
|
17
19
|
assets: Record<string, string>;
|
|
18
20
|
}) | {
|
|
19
21
|
assets: Record<string, string>;
|
|
20
22
|
};
|
|
21
|
-
getPlugins: () => any;
|
|
22
|
-
getValidKeys: () => any;
|
|
23
23
|
getRoutes: (PluginManager: any) => any;
|
|
24
24
|
getClientRootComponent: (PluginManager: any) => any;
|
|
25
25
|
createHistory: (opts: any) => any;
|
|
26
26
|
helmetContext?: any;
|
|
27
27
|
ServerInsertedHTMLContext: React.Context<ServerInsertedHTMLHook | null>;
|
|
28
|
+
htmlPageOpts: IhtmlPageOpts;
|
|
29
|
+
__INTERNAL_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
|
|
30
|
+
pureApp: boolean;
|
|
31
|
+
pureHtml: boolean;
|
|
32
|
+
};
|
|
33
|
+
mountElementId: string;
|
|
28
34
|
}
|
|
29
35
|
export declare function createMarkupGenerator(opts: CreateRequestHandlerOptions): (url: string) => Promise<unknown>;
|
|
30
|
-
|
|
36
|
+
declare type IExpressRequestHandlerArgs = Parameters<RequestHandler>;
|
|
37
|
+
declare type IWorkerRequestHandlerArgs = [
|
|
38
|
+
ev: FetchEvent,
|
|
39
|
+
opts?: {
|
|
40
|
+
modifyResponse?: (res: Response) => Promise<Response> | Response;
|
|
41
|
+
}
|
|
42
|
+
];
|
|
43
|
+
export default function createRequestHandler(opts: CreateRequestHandlerOptions): (...args: IExpressRequestHandlerArgs | IWorkerRequestHandlerArgs) => Promise<void>;
|
|
31
44
|
export declare function createUmiHandler(opts: CreateRequestHandlerOptions): (req: UmiRequest, params?: CreateRequestHandlerOptions) => Promise<NodeJS.ReadableStream>;
|
|
32
45
|
export declare function createUmiServerLoader(opts: CreateRequestHandlerOptions): (req: UmiRequest) => Promise<any>;
|
|
46
|
+
export declare function createAppRootElement(opts: CreateRequestHandlerOptions): (...args: IExpressRequestHandlerArgs | IWorkerRequestHandlerArgs) => Promise<() => React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined>;
|
|
33
47
|
export {};
|
package/dist/ssr.js
CHANGED
|
@@ -29,6 +29,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
29
29
|
// src/ssr.ts
|
|
30
30
|
var ssr_exports = {};
|
|
31
31
|
__export(ssr_exports, {
|
|
32
|
+
createAppRootElement: () => createAppRootElement,
|
|
32
33
|
createMarkupGenerator: () => createMarkupGenerator,
|
|
33
34
|
createUmiHandler: () => createUmiHandler,
|
|
34
35
|
createUmiServerLoader: () => createUmiServerLoader,
|
|
@@ -39,7 +40,16 @@ var import_react = __toESM(require("react"));
|
|
|
39
40
|
var ReactDomServer = __toESM(require("react-dom/server"));
|
|
40
41
|
var import_react_router_dom = require("react-router-dom");
|
|
41
42
|
var import_stream = require("stream");
|
|
42
|
-
var
|
|
43
|
+
var MetaLoaderResultKeys = /* @__PURE__ */ ((MetaLoaderResultKeys2) => {
|
|
44
|
+
MetaLoaderResultKeys2["Title"] = "title";
|
|
45
|
+
MetaLoaderResultKeys2["Description"] = "description";
|
|
46
|
+
MetaLoaderResultKeys2["Keywords"] = "keywords";
|
|
47
|
+
MetaLoaderResultKeys2["Lang"] = "lang";
|
|
48
|
+
MetaLoaderResultKeys2["Metas"] = "metas";
|
|
49
|
+
return MetaLoaderResultKeys2;
|
|
50
|
+
})(MetaLoaderResultKeys || {});
|
|
51
|
+
var createJSXProvider = (Provider) => {
|
|
52
|
+
const serverInsertedHTMLCallbacks = /* @__PURE__ */ new Set();
|
|
43
53
|
const JSXProvider = (props) => {
|
|
44
54
|
const addInsertedHtml = import_react.default.useCallback(
|
|
45
55
|
(handler) => {
|
|
@@ -52,26 +62,20 @@ var createJSXProvider = (Provider, serverInsertedHTMLCallbacks) => {
|
|
|
52
62
|
value: addInsertedHtml
|
|
53
63
|
});
|
|
54
64
|
};
|
|
55
|
-
return JSXProvider;
|
|
65
|
+
return [JSXProvider, serverInsertedHTMLCallbacks];
|
|
56
66
|
};
|
|
57
67
|
function createJSXGenerator(opts) {
|
|
58
68
|
return async (url, serverLoaderArgs) => {
|
|
59
69
|
const {
|
|
60
70
|
routesWithServerLoader,
|
|
61
|
-
|
|
62
|
-
getPlugins,
|
|
63
|
-
getValidKeys,
|
|
71
|
+
pluginManager,
|
|
64
72
|
getRoutes,
|
|
65
73
|
createHistory,
|
|
66
74
|
sourceDir
|
|
67
75
|
} = opts;
|
|
68
76
|
createHistory({ type: "memory", initialEntries: [url], initialIndex: 1 });
|
|
69
|
-
const pluginManager = PluginManager.create({
|
|
70
|
-
plugins: getPlugins(),
|
|
71
|
-
validKeys: getValidKeys()
|
|
72
|
-
});
|
|
73
77
|
const { routes, routeComponents } = await getRoutes(pluginManager);
|
|
74
|
-
|
|
78
|
+
pluginManager.applyPlugins({
|
|
75
79
|
key: "patchRoutes",
|
|
76
80
|
type: "event",
|
|
77
81
|
args: {
|
|
@@ -84,7 +88,6 @@ function createJSXGenerator(opts) {
|
|
|
84
88
|
return;
|
|
85
89
|
}
|
|
86
90
|
const loaderData = {};
|
|
87
|
-
const metadata = {};
|
|
88
91
|
await Promise.all(
|
|
89
92
|
matches.filter((id) => routes[id].hasServerLoader).map(
|
|
90
93
|
(id) => new Promise(async (resolve) => {
|
|
@@ -94,15 +97,19 @@ function createJSXGenerator(opts) {
|
|
|
94
97
|
serverLoaderArgs
|
|
95
98
|
});
|
|
96
99
|
if (routes[id].hasMetadataLoader) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
100
|
+
const metadataLoaderData = await executeMetadataLoader({
|
|
101
|
+
routesWithServerLoader,
|
|
102
|
+
routeKey: id,
|
|
103
|
+
serverLoaderArgs,
|
|
104
|
+
serverLoaderData: loaderData[id]
|
|
105
|
+
});
|
|
106
|
+
metadataLoaderData && Object.entries(metadataLoaderData).forEach(([k, v]) => {
|
|
107
|
+
if (Array.isArray(v)) {
|
|
108
|
+
opts.htmlPageOpts[k] = (opts.htmlPageOpts[k] || []).concat(v);
|
|
109
|
+
} else {
|
|
110
|
+
opts.htmlPageOpts[k] = v;
|
|
111
|
+
}
|
|
112
|
+
});
|
|
106
113
|
}
|
|
107
114
|
resolve();
|
|
108
115
|
})
|
|
@@ -116,7 +123,9 @@ function createJSXGenerator(opts) {
|
|
|
116
123
|
location: url,
|
|
117
124
|
manifest,
|
|
118
125
|
loaderData,
|
|
119
|
-
|
|
126
|
+
htmlPageOpts: opts.htmlPageOpts,
|
|
127
|
+
__INTERNAL_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: opts.__INTERNAL_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
|
|
128
|
+
mountElementId: opts.mountElementId
|
|
120
129
|
};
|
|
121
130
|
const element = await opts.getClientRootComponent(
|
|
122
131
|
context
|
|
@@ -127,13 +136,19 @@ function createJSXGenerator(opts) {
|
|
|
127
136
|
};
|
|
128
137
|
};
|
|
129
138
|
}
|
|
130
|
-
var
|
|
139
|
+
var SERVER_INSERTED_HTML = "umi-server-inserted-html";
|
|
140
|
+
var getGenerateStaticHTML = (serverInsertedHTMLCallbacks, opts) => {
|
|
141
|
+
const children = import_react.default.createElement(import_react.default.Fragment, {
|
|
142
|
+
children: Array.from(serverInsertedHTMLCallbacks || []).map(
|
|
143
|
+
(callback) => callback()
|
|
144
|
+
)
|
|
145
|
+
});
|
|
131
146
|
return ReactDomServer.renderToString(
|
|
132
|
-
import_react.default.createElement(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
147
|
+
(opts == null ? void 0 : opts.wrapper) ? import_react.default.createElement(
|
|
148
|
+
"div",
|
|
149
|
+
{ id: SERVER_INSERTED_HTML, hidden: true },
|
|
150
|
+
children
|
|
151
|
+
) : children
|
|
137
152
|
) || "";
|
|
138
153
|
};
|
|
139
154
|
function createMarkupGenerator(opts) {
|
|
@@ -142,10 +157,8 @@ function createMarkupGenerator(opts) {
|
|
|
142
157
|
const jsx = await jsxGeneratorDeferrer(url);
|
|
143
158
|
if (jsx) {
|
|
144
159
|
return new Promise(async (resolve, reject) => {
|
|
145
|
-
const serverInsertedHTMLCallbacks =
|
|
146
|
-
|
|
147
|
-
opts.ServerInsertedHTMLContext.Provider,
|
|
148
|
-
serverInsertedHTMLCallbacks
|
|
160
|
+
const [JSXProvider, serverInsertedHTMLCallbacks] = createJSXProvider(
|
|
161
|
+
opts.ServerInsertedHTMLContext.Provider
|
|
149
162
|
);
|
|
150
163
|
let chunks = [];
|
|
151
164
|
const writable = new import_stream.Writable();
|
|
@@ -155,7 +168,10 @@ function createMarkupGenerator(opts) {
|
|
|
155
168
|
};
|
|
156
169
|
writable.on("finish", async () => {
|
|
157
170
|
let html = Buffer.concat(chunks).toString("utf8");
|
|
158
|
-
|
|
171
|
+
const serverHTML = getGenerateStaticHTML(serverInsertedHTMLCallbacks);
|
|
172
|
+
if (serverHTML) {
|
|
173
|
+
html = html.replace(/<\/head>/, `${serverHTML}</head>`);
|
|
174
|
+
}
|
|
159
175
|
if (opts.helmetContext) {
|
|
160
176
|
html = html.replace(
|
|
161
177
|
/(<\/head>)/,
|
|
@@ -177,6 +193,7 @@ function createMarkupGenerator(opts) {
|
|
|
177
193
|
onShellReady() {
|
|
178
194
|
stream.pipe(writable);
|
|
179
195
|
},
|
|
196
|
+
bootstrapScripts: [jsx.manifest.assets["umi.js"] || "/umi.js"],
|
|
180
197
|
onError: reject
|
|
181
198
|
}
|
|
182
199
|
);
|
|
@@ -185,50 +202,200 @@ function createMarkupGenerator(opts) {
|
|
|
185
202
|
return "";
|
|
186
203
|
};
|
|
187
204
|
}
|
|
205
|
+
var normalizeRequest = (...args) => {
|
|
206
|
+
var _a, _b;
|
|
207
|
+
let request;
|
|
208
|
+
let serverLoaderRequest;
|
|
209
|
+
let serverLoaderArgs;
|
|
210
|
+
if (process.env.SSR_BUILD_TARGET === "worker") {
|
|
211
|
+
const [ev] = args;
|
|
212
|
+
const { pathname, searchParams } = new URL(ev.request.url);
|
|
213
|
+
request = {
|
|
214
|
+
url: ev.request.url,
|
|
215
|
+
pathname,
|
|
216
|
+
headers: ev.request.headers,
|
|
217
|
+
query: {
|
|
218
|
+
route: searchParams.get("route"),
|
|
219
|
+
url: searchParams.get("url")
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
} else {
|
|
223
|
+
const [req] = args;
|
|
224
|
+
request = {
|
|
225
|
+
url: `${req.protocol}://${req.get("host")}${req.originalUrl}`,
|
|
226
|
+
pathname: req.url,
|
|
227
|
+
headers: req.headers,
|
|
228
|
+
query: {
|
|
229
|
+
route: (_a = req.query.route) == null ? void 0 : _a.toString(),
|
|
230
|
+
url: (_b = req.query.url) == null ? void 0 : _b.toString()
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
if (request.pathname.startsWith("/__serverLoader") && request.query.route && request.query.url) {
|
|
235
|
+
serverLoaderRequest = new Request(request.query.url, {
|
|
236
|
+
headers: request.headers
|
|
237
|
+
});
|
|
238
|
+
serverLoaderArgs = {
|
|
239
|
+
request: serverLoaderRequest
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
return {
|
|
243
|
+
request,
|
|
244
|
+
serverLoaderArgs
|
|
245
|
+
};
|
|
246
|
+
};
|
|
188
247
|
function createRequestHandler(opts) {
|
|
189
248
|
const jsxGeneratorDeferrer = createJSXGenerator(opts);
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
249
|
+
const normalizeHandlerArgs = (...args) => {
|
|
250
|
+
let ret;
|
|
251
|
+
const { request } = normalizeRequest(...args);
|
|
252
|
+
const replaceServerHTMLScript = `<script>!function(){var e=document.getElementById("${SERVER_INSERTED_HTML}");e&&(Array.from(e.children).forEach(e=>{document.head.appendChild(e)}),e.remove())}();</script>`;
|
|
253
|
+
if (process.env.SSR_BUILD_TARGET === "worker") {
|
|
254
|
+
const [ev, workerOpts] = args;
|
|
255
|
+
let asyncRespondWith;
|
|
256
|
+
ev.respondWith(new Promise((r) => asyncRespondWith = r));
|
|
257
|
+
ret = {
|
|
258
|
+
req: request,
|
|
259
|
+
async sendServerLoader(data) {
|
|
260
|
+
let res = new Response(JSON.stringify(data), {
|
|
261
|
+
headers: {
|
|
262
|
+
"content-type": "application/json; charset=utf-8"
|
|
263
|
+
},
|
|
264
|
+
status: 200
|
|
265
|
+
});
|
|
266
|
+
if (workerOpts == null ? void 0 : workerOpts.modifyResponse) {
|
|
267
|
+
res = await workerOpts.modifyResponse(res);
|
|
268
|
+
}
|
|
269
|
+
asyncRespondWith(res);
|
|
270
|
+
},
|
|
271
|
+
async sendPage(jsx) {
|
|
272
|
+
const [JSXProvider, serverInsertedHTMLCallbacks] = createJSXProvider(
|
|
273
|
+
opts.ServerInsertedHTMLContext.Provider
|
|
274
|
+
);
|
|
275
|
+
const stream = await ReactDomServer.renderToReadableStream(
|
|
276
|
+
import_react.default.createElement(JSXProvider, void 0, jsx.element),
|
|
277
|
+
{
|
|
278
|
+
// why not bootstrap umi.js
|
|
279
|
+
// ER will auto inject
|
|
280
|
+
// bootstrapScripts: [jsx.manifest.assets['umi.js'] || '/umi.js'],
|
|
281
|
+
onError(x) {
|
|
282
|
+
console.error(x);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
);
|
|
286
|
+
const transformStream = new TransformStream({
|
|
287
|
+
flush(controller) {
|
|
288
|
+
if (serverInsertedHTMLCallbacks.size) {
|
|
289
|
+
const serverHTML = getGenerateStaticHTML(
|
|
290
|
+
serverInsertedHTMLCallbacks,
|
|
291
|
+
{ wrapper: true }
|
|
292
|
+
);
|
|
293
|
+
controller.enqueue(serverHTML);
|
|
294
|
+
controller.enqueue(replaceServerHTMLScript);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
let res = new Response(stream.pipeThrough(transformStream), {
|
|
299
|
+
headers: {
|
|
300
|
+
"content-type": "text/html; charset=utf-8"
|
|
301
|
+
},
|
|
302
|
+
status: 200
|
|
303
|
+
});
|
|
304
|
+
if (workerOpts == null ? void 0 : workerOpts.modifyResponse) {
|
|
305
|
+
res = await workerOpts.modifyResponse(res);
|
|
306
|
+
}
|
|
307
|
+
asyncRespondWith(res);
|
|
308
|
+
},
|
|
309
|
+
otherwise() {
|
|
310
|
+
throw new Error("no page resource");
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
} else {
|
|
314
|
+
const [_, res, next] = args;
|
|
315
|
+
ret = {
|
|
316
|
+
req: request,
|
|
317
|
+
sendServerLoader(data) {
|
|
318
|
+
res.status(200).json(data);
|
|
319
|
+
},
|
|
320
|
+
async sendPage(jsx) {
|
|
321
|
+
const [JSXProvider, serverInsertedHTMLCallbacks] = createJSXProvider(
|
|
322
|
+
opts.ServerInsertedHTMLContext.Provider
|
|
323
|
+
);
|
|
324
|
+
const writable = new import_stream.Writable();
|
|
325
|
+
res.type("html");
|
|
326
|
+
writable._write = (chunk, _encoding, cb) => {
|
|
327
|
+
res.write(chunk);
|
|
328
|
+
cb();
|
|
329
|
+
};
|
|
330
|
+
writable.on("finish", async () => {
|
|
331
|
+
if (serverInsertedHTMLCallbacks.size) {
|
|
332
|
+
res.write(
|
|
333
|
+
getGenerateStaticHTML(serverInsertedHTMLCallbacks, {
|
|
334
|
+
wrapper: true
|
|
335
|
+
})
|
|
336
|
+
);
|
|
337
|
+
res.write(replaceServerHTMLScript);
|
|
338
|
+
}
|
|
339
|
+
res.end();
|
|
340
|
+
});
|
|
341
|
+
const stream = ReactDomServer.renderToPipeableStream(
|
|
342
|
+
import_react.default.createElement(JSXProvider, void 0, jsx.element),
|
|
343
|
+
{
|
|
344
|
+
bootstrapScripts: [jsx.manifest.assets["umi.js"] || "/umi.js"],
|
|
345
|
+
onShellReady() {
|
|
346
|
+
stream.pipe(writable);
|
|
347
|
+
},
|
|
348
|
+
onError(x) {
|
|
349
|
+
console.error(x);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
);
|
|
353
|
+
},
|
|
354
|
+
otherwise: next
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
return ret;
|
|
358
|
+
};
|
|
359
|
+
return async function unifiedRequestHandler(...args) {
|
|
360
|
+
const { req, sendServerLoader, sendPage, otherwise } = normalizeHandlerArgs(
|
|
361
|
+
...args
|
|
362
|
+
);
|
|
363
|
+
if (req.pathname.startsWith("/__serverLoader") && req.query.route && req.query.url) {
|
|
364
|
+
const { serverLoaderArgs } = normalizeRequest(...args);
|
|
195
365
|
const data = await executeLoader({
|
|
196
366
|
routeKey: req.query.route,
|
|
197
367
|
routesWithServerLoader: opts.routesWithServerLoader,
|
|
198
|
-
serverLoaderArgs
|
|
368
|
+
serverLoaderArgs
|
|
199
369
|
});
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
res.write(await getGenerateStaticHTML());
|
|
217
|
-
res.end();
|
|
218
|
-
});
|
|
219
|
-
const stream = await ReactDomServer.renderToPipeableStream(jsx.element, {
|
|
220
|
-
bootstrapScripts: [jsx.manifest.assets["umi.js"] || "/umi.js"],
|
|
221
|
-
onShellReady() {
|
|
222
|
-
stream.pipe(writable);
|
|
223
|
-
},
|
|
224
|
-
onError(x) {
|
|
225
|
-
console.error(x);
|
|
370
|
+
await sendServerLoader(data);
|
|
371
|
+
} else {
|
|
372
|
+
const render = opts.pluginManager.applyPlugins({
|
|
373
|
+
key: "render",
|
|
374
|
+
type: "compose",
|
|
375
|
+
initialValue: () => jsxGeneratorDeferrer(req.pathname, {
|
|
376
|
+
request: new Request(req.url, {
|
|
377
|
+
headers: req.headers
|
|
378
|
+
})
|
|
379
|
+
})
|
|
380
|
+
});
|
|
381
|
+
const jsx = await render();
|
|
382
|
+
if (jsx) {
|
|
383
|
+
await sendPage(jsx);
|
|
384
|
+
} else {
|
|
385
|
+
await otherwise();
|
|
226
386
|
}
|
|
227
|
-
}
|
|
387
|
+
}
|
|
228
388
|
};
|
|
229
389
|
}
|
|
230
390
|
function createUmiHandler(opts) {
|
|
391
|
+
let isWarned = false;
|
|
231
392
|
return async function(req, params) {
|
|
393
|
+
if (!isWarned) {
|
|
394
|
+
console.warn(
|
|
395
|
+
"[umi] `renderRoot` is deprecated, please use `requestHandler` instead"
|
|
396
|
+
);
|
|
397
|
+
isWarned = true;
|
|
398
|
+
}
|
|
232
399
|
const jsxGeneratorDeferrer = createJSXGenerator({
|
|
233
400
|
...opts,
|
|
234
401
|
...params
|
|
@@ -247,7 +414,14 @@ function createUmiHandler(opts) {
|
|
|
247
414
|
};
|
|
248
415
|
}
|
|
249
416
|
function createUmiServerLoader(opts) {
|
|
417
|
+
let isWarned = false;
|
|
250
418
|
return async function(req) {
|
|
419
|
+
if (!isWarned) {
|
|
420
|
+
console.warn(
|
|
421
|
+
"[umi] `serverLoader` is deprecated, please use `requestHandler` instead"
|
|
422
|
+
);
|
|
423
|
+
isWarned = true;
|
|
424
|
+
}
|
|
251
425
|
const query = Object.fromEntries(new URL(req.url).searchParams);
|
|
252
426
|
const serverLoaderRequest = new Request(query.url, {
|
|
253
427
|
headers: req.headers
|
|
@@ -259,6 +433,14 @@ function createUmiServerLoader(opts) {
|
|
|
259
433
|
});
|
|
260
434
|
};
|
|
261
435
|
}
|
|
436
|
+
function createAppRootElement(opts) {
|
|
437
|
+
return async (...args) => {
|
|
438
|
+
const jsxGeneratorDeferrer = createJSXGenerator(opts);
|
|
439
|
+
const { request, serverLoaderArgs } = normalizeRequest(...args);
|
|
440
|
+
const jsx = await jsxGeneratorDeferrer(request.pathname, serverLoaderArgs);
|
|
441
|
+
return () => jsx == null ? void 0 : jsx.element;
|
|
442
|
+
};
|
|
443
|
+
}
|
|
262
444
|
function matchRoutesForSSR(reqUrl, routesById) {
|
|
263
445
|
var _a;
|
|
264
446
|
return ((_a = (0, import_react_router_dom.matchRoutes)(createClientRoutes({ routesById }), reqUrl)) == null ? void 0 : _a.map(
|
|
@@ -296,23 +478,24 @@ async function executeLoader(params) {
|
|
|
296
478
|
return mod.serverLoader(serverLoaderArgs);
|
|
297
479
|
}
|
|
298
480
|
async function executeMetadataLoader(params) {
|
|
299
|
-
const {
|
|
300
|
-
routesWithServerLoader,
|
|
301
|
-
routeKey,
|
|
302
|
-
serverLoaderArgs,
|
|
303
|
-
serverLoaderData
|
|
304
|
-
} = params;
|
|
481
|
+
const { routesWithServerLoader, routeKey, serverLoaderData } = params;
|
|
305
482
|
const mod = await routesWithServerLoader[routeKey]();
|
|
306
483
|
if (!mod.serverLoader || typeof mod.serverLoader !== "function") {
|
|
307
484
|
return;
|
|
308
485
|
}
|
|
309
|
-
|
|
310
|
-
serverLoaderData
|
|
311
|
-
serverLoaderArgs
|
|
486
|
+
const loaderDatas = mod.metadataLoader(
|
|
487
|
+
serverLoaderData
|
|
312
488
|
);
|
|
489
|
+
const result = {};
|
|
490
|
+
Object.values(MetaLoaderResultKeys).forEach((key) => {
|
|
491
|
+
if (loaderDatas == null ? void 0 : loaderDatas[key])
|
|
492
|
+
result[key] = loaderDatas[key];
|
|
493
|
+
});
|
|
494
|
+
return result;
|
|
313
495
|
}
|
|
314
496
|
// Annotate the CommonJS export names for ESM import in node:
|
|
315
497
|
0 && (module.exports = {
|
|
498
|
+
createAppRootElement,
|
|
316
499
|
createMarkupGenerator,
|
|
317
500
|
createUmiHandler,
|
|
318
501
|
createUmiServerLoader
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
export interface IOpts {
|
|
2
|
+
base: string;
|
|
3
|
+
routes: Record<string, {
|
|
4
|
+
path: string;
|
|
5
|
+
file: string;
|
|
6
|
+
id: string;
|
|
7
|
+
parentId?: string;
|
|
8
|
+
}>;
|
|
9
|
+
links?: Record<string, string>[];
|
|
10
|
+
metas?: Record<string, string>[];
|
|
11
|
+
styles?: (Record<string, string> | string)[];
|
|
12
|
+
favicons?: string[];
|
|
13
|
+
title?: string;
|
|
14
|
+
headScripts?: (Record<string, string> | string)[];
|
|
15
|
+
scripts?: (Record<string, string> | string)[];
|
|
16
|
+
mountElementId?: string;
|
|
17
|
+
esmScript?: boolean;
|
|
18
|
+
modifyHTML?: (html: string, args: {
|
|
19
|
+
path?: string;
|
|
20
|
+
}) => Promise<string>;
|
|
21
|
+
historyType?: 'hash' | 'browser';
|
|
22
|
+
}
|
|
23
|
+
export declare type IUserExtraRoute = string | {
|
|
24
|
+
path: string;
|
|
25
|
+
prerender: boolean;
|
|
26
|
+
};
|
|
1
27
|
export interface IRoute {
|
|
2
28
|
id: string;
|
|
3
29
|
path?: string;
|
|
@@ -30,5 +56,13 @@ export interface IMetadata {
|
|
|
30
56
|
lang?: string;
|
|
31
57
|
metas?: IMetaTag[];
|
|
32
58
|
}
|
|
59
|
+
export interface IhtmlPageOpts extends IMetadata {
|
|
60
|
+
headScripts?: (Record<string, string> | string)[];
|
|
61
|
+
links?: Record<string, string>[];
|
|
62
|
+
styles?: string[];
|
|
63
|
+
favicons?: string[];
|
|
64
|
+
scripts?: (Record<string, string> | string)[];
|
|
65
|
+
[key: string]: any;
|
|
66
|
+
}
|
|
33
67
|
export declare type MetadataLoader<T = any> = (serverLoaderData: T, req?: IServerLoaderArgs) => LoaderReturn<IMetadata>;
|
|
34
68
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umijs/server",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.6-alpha.0",
|
|
4
4
|
"description": "@umijs/server",
|
|
5
5
|
"homepage": "https://github.com/umijs/umi/tree/master/packages/server#readme",
|
|
6
6
|
"bugs": "https://github.com/umijs/umi/issues",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"react": "18.1.0",
|
|
20
20
|
"react-dom": "18.1.0",
|
|
21
21
|
"react-router-dom": "6.3.0",
|
|
22
|
-
"@umijs/bundler-utils": "4.2.
|
|
22
|
+
"@umijs/bundler-utils": "4.2.6-alpha.0"
|
|
23
23
|
},
|
|
24
24
|
"publishConfig": {
|
|
25
25
|
"access": "public"
|