@umijs/server 4.2.6-alpha.6 → 4.2.6

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 CHANGED
@@ -1,7 +1,5 @@
1
- /// <reference lib="webworker" />
2
- import type { RequestHandler } from '@umijs/bundler-utils/compiled/express';
3
1
  import React from 'react';
4
- import type { IhtmlPageOpts, UmiRequest } from './types';
2
+ import type { UmiRequest } from './types';
5
3
  interface RouteLoaders {
6
4
  [key: string]: () => Promise<any>;
7
5
  }
@@ -14,34 +12,22 @@ interface CreateRequestServerlessOptions {
14
12
  }
15
13
  interface CreateRequestHandlerOptions extends CreateRequestServerlessOptions {
16
14
  routesWithServerLoader: RouteLoaders;
17
- pluginManager: any;
15
+ PluginManager: any;
18
16
  manifest: ((sourceDir?: string) => {
19
17
  assets: Record<string, string>;
20
18
  }) | {
21
19
  assets: Record<string, string>;
22
20
  };
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;
34
28
  }
35
29
  export declare function createMarkupGenerator(opts: CreateRequestHandlerOptions): (url: string) => Promise<unknown>;
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>;
30
+ export default function createRequestHandler(opts: CreateRequestHandlerOptions): (req: any, res: any, next: any) => Promise<any>;
44
31
  export declare function createUmiHandler(opts: CreateRequestHandlerOptions): (req: UmiRequest, params?: CreateRequestHandlerOptions) => Promise<NodeJS.ReadableStream>;
45
32
  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>;
47
33
  export {};
package/dist/ssr.js CHANGED
@@ -29,7 +29,6 @@ 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,
33
32
  createMarkupGenerator: () => createMarkupGenerator,
34
33
  createUmiHandler: () => createUmiHandler,
35
34
  createUmiServerLoader: () => createUmiServerLoader,
@@ -40,16 +39,7 @@ var import_react = __toESM(require("react"));
40
39
  var ReactDomServer = __toESM(require("react-dom/server"));
41
40
  var import_react_router_dom = require("react-router-dom");
42
41
  var import_stream = require("stream");
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();
42
+ var createJSXProvider = (Provider, serverInsertedHTMLCallbacks) => {
53
43
  const JSXProvider = (props) => {
54
44
  const addInsertedHtml = import_react.default.useCallback(
55
45
  (handler) => {
@@ -62,20 +52,26 @@ var createJSXProvider = (Provider) => {
62
52
  value: addInsertedHtml
63
53
  });
64
54
  };
65
- return [JSXProvider, serverInsertedHTMLCallbacks];
55
+ return JSXProvider;
66
56
  };
67
57
  function createJSXGenerator(opts) {
68
58
  return async (url, serverLoaderArgs) => {
69
59
  const {
70
60
  routesWithServerLoader,
71
- pluginManager,
61
+ PluginManager,
62
+ getPlugins,
63
+ getValidKeys,
72
64
  getRoutes,
73
65
  createHistory,
74
66
  sourceDir
75
67
  } = opts;
76
68
  createHistory({ type: "memory", initialEntries: [url], initialIndex: 1 });
69
+ const pluginManager = PluginManager.create({
70
+ plugins: getPlugins(),
71
+ validKeys: getValidKeys()
72
+ });
77
73
  const { routes, routeComponents } = await getRoutes(pluginManager);
78
- pluginManager.applyPlugins({
74
+ await pluginManager.applyPlugins({
79
75
  key: "patchRoutes",
80
76
  type: "event",
81
77
  args: {
@@ -88,6 +84,7 @@ function createJSXGenerator(opts) {
88
84
  return;
89
85
  }
90
86
  const loaderData = {};
87
+ const metadata = {};
91
88
  await Promise.all(
92
89
  matches.filter((id) => routes[id].hasServerLoader).map(
93
90
  (id) => new Promise(async (resolve) => {
@@ -97,19 +94,15 @@ function createJSXGenerator(opts) {
97
94
  serverLoaderArgs
98
95
  });
99
96
  if (routes[id].hasMetadataLoader) {
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
- });
97
+ Object.assign(
98
+ metadata,
99
+ await executeMetadataLoader({
100
+ routesWithServerLoader,
101
+ routeKey: id,
102
+ serverLoaderArgs,
103
+ serverLoaderData: loaderData[id]
104
+ })
105
+ );
113
106
  }
114
107
  resolve();
115
108
  })
@@ -123,9 +116,7 @@ function createJSXGenerator(opts) {
123
116
  location: url,
124
117
  manifest,
125
118
  loaderData,
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
119
+ metadata
129
120
  };
130
121
  const element = await opts.getClientRootComponent(
131
122
  context
@@ -136,19 +127,13 @@ function createJSXGenerator(opts) {
136
127
  };
137
128
  };
138
129
  }
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
- });
130
+ var getGenerateStaticHTML = (serverInsertedHTMLCallbacks) => {
146
131
  return ReactDomServer.renderToString(
147
- (opts == null ? void 0 : opts.wrapper) ? import_react.default.createElement(
148
- "div",
149
- { id: SERVER_INSERTED_HTML, hidden: true },
150
- children
151
- ) : children
132
+ import_react.default.createElement(import_react.default.Fragment, {
133
+ children: Array.from(serverInsertedHTMLCallbacks || []).map(
134
+ (callback) => callback()
135
+ )
136
+ })
152
137
  ) || "";
153
138
  };
154
139
  function createMarkupGenerator(opts) {
@@ -157,8 +142,10 @@ function createMarkupGenerator(opts) {
157
142
  const jsx = await jsxGeneratorDeferrer(url);
158
143
  if (jsx) {
159
144
  return new Promise(async (resolve, reject) => {
160
- const [JSXProvider, serverInsertedHTMLCallbacks] = createJSXProvider(
161
- opts.ServerInsertedHTMLContext.Provider
145
+ const serverInsertedHTMLCallbacks = /* @__PURE__ */ new Set();
146
+ const JSXProvider = createJSXProvider(
147
+ opts.ServerInsertedHTMLContext.Provider,
148
+ serverInsertedHTMLCallbacks
162
149
  );
163
150
  let chunks = [];
164
151
  const writable = new import_stream.Writable();
@@ -168,10 +155,7 @@ function createMarkupGenerator(opts) {
168
155
  };
169
156
  writable.on("finish", async () => {
170
157
  let html = Buffer.concat(chunks).toString("utf8");
171
- const serverHTML = getGenerateStaticHTML(serverInsertedHTMLCallbacks);
172
- if (serverHTML) {
173
- html = html.replace(/<\/head>/, `${serverHTML}</head>`);
174
- }
158
+ html += await getGenerateStaticHTML(serverInsertedHTMLCallbacks);
175
159
  if (opts.helmetContext) {
176
160
  html = html.replace(
177
161
  /(<\/head>)/,
@@ -193,7 +177,6 @@ function createMarkupGenerator(opts) {
193
177
  onShellReady() {
194
178
  stream.pipe(writable);
195
179
  },
196
- bootstrapScripts: [jsx.manifest.assets["umi.js"] || "/umi.js"],
197
180
  onError: reject
198
181
  }
199
182
  );
@@ -202,200 +185,50 @@ function createMarkupGenerator(opts) {
202
185
  return "";
203
186
  };
204
187
  }
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
- };
247
188
  function createRequestHandler(opts) {
248
189
  const jsxGeneratorDeferrer = createJSXGenerator(opts);
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);
190
+ return async function(req, res, next) {
191
+ if (req.url.startsWith("/__serverLoader") && req.query.route) {
192
+ const serverLoaderRequest = new Request(req.query.url, {
193
+ headers: req.headers
194
+ });
365
195
  const data = await executeLoader({
366
196
  routeKey: req.query.route,
367
197
  routesWithServerLoader: opts.routesWithServerLoader,
368
- serverLoaderArgs
369
- });
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
- })
198
+ serverLoaderArgs: { request: serverLoaderRequest }
380
199
  });
381
- const jsx = await render();
382
- if (jsx) {
383
- await sendPage(jsx);
384
- } else {
385
- await otherwise();
386
- }
200
+ res.status(200).json(data);
201
+ return;
387
202
  }
203
+ const fullUrl = `${req.protocol}://${req.get("host")}${req.originalUrl}`;
204
+ const request = new Request(fullUrl, {
205
+ headers: req.headers
206
+ });
207
+ const jsx = await jsxGeneratorDeferrer(req.url, { request });
208
+ if (!jsx)
209
+ return next();
210
+ const writable = new import_stream.Writable();
211
+ writable._write = (chunk, _encoding, next2) => {
212
+ res.write(chunk);
213
+ next2();
214
+ };
215
+ writable.on("finish", async () => {
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);
226
+ }
227
+ });
388
228
  };
389
229
  }
390
230
  function createUmiHandler(opts) {
391
- let isWarned = false;
392
231
  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
- }
399
232
  const jsxGeneratorDeferrer = createJSXGenerator({
400
233
  ...opts,
401
234
  ...params
@@ -414,14 +247,7 @@ function createUmiHandler(opts) {
414
247
  };
415
248
  }
416
249
  function createUmiServerLoader(opts) {
417
- let isWarned = false;
418
250
  return async function(req) {
419
- if (!isWarned) {
420
- console.warn(
421
- "[umi] `serverLoader` is deprecated, please use `requestHandler` instead"
422
- );
423
- isWarned = true;
424
- }
425
251
  const query = Object.fromEntries(new URL(req.url).searchParams);
426
252
  const serverLoaderRequest = new Request(query.url, {
427
253
  headers: req.headers
@@ -433,14 +259,6 @@ function createUmiServerLoader(opts) {
433
259
  });
434
260
  };
435
261
  }
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
- }
444
262
  function matchRoutesForSSR(reqUrl, routesById) {
445
263
  var _a;
446
264
  return ((_a = (0, import_react_router_dom.matchRoutes)(createClientRoutes({ routesById }), reqUrl)) == null ? void 0 : _a.map(
@@ -478,24 +296,23 @@ async function executeLoader(params) {
478
296
  return mod.serverLoader(serverLoaderArgs);
479
297
  }
480
298
  async function executeMetadataLoader(params) {
481
- const { routesWithServerLoader, routeKey, serverLoaderData } = params;
299
+ const {
300
+ routesWithServerLoader,
301
+ routeKey,
302
+ serverLoaderArgs,
303
+ serverLoaderData
304
+ } = params;
482
305
  const mod = await routesWithServerLoader[routeKey]();
483
306
  if (!mod.serverLoader || typeof mod.serverLoader !== "function") {
484
307
  return;
485
308
  }
486
- const loaderDatas = mod.metadataLoader(
487
- serverLoaderData
309
+ return mod.metadataLoader(
310
+ serverLoaderData,
311
+ serverLoaderArgs
488
312
  );
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;
495
313
  }
496
314
  // Annotate the CommonJS export names for ESM import in node:
497
315
  0 && (module.exports = {
498
- createAppRootElement,
499
316
  createMarkupGenerator,
500
317
  createUmiHandler,
501
318
  createUmiServerLoader
package/dist/types.d.ts CHANGED
@@ -1,29 +1,3 @@
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
- };
27
1
  export interface IRoute {
28
2
  id: string;
29
3
  path?: string;
@@ -56,13 +30,5 @@ export interface IMetadata {
56
30
  lang?: string;
57
31
  metas?: IMetaTag[];
58
32
  }
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
- }
67
33
  export declare type MetadataLoader<T = any> = (serverLoaderData: T, req?: IServerLoaderArgs) => LoaderReturn<IMetadata>;
68
34
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umijs/server",
3
- "version": "4.2.6-alpha.6",
3
+ "version": "4.2.6",
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.6-alpha.6"
22
+ "@umijs/bundler-utils": "4.2.6"
23
23
  },
24
24
  "publishConfig": {
25
25
  "access": "public"