@modern-js/prod-server 2.46.1 → 2.47.1-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.
Files changed (169) hide show
  1. package/README.md +20 -16
  2. package/dist/cjs/{libs/hook-api/route.js → error.js} +16 -25
  3. package/dist/cjs/index.js +46 -24
  4. package/dist/esm/error.js +15 -0
  5. package/dist/esm/index.js +105 -19
  6. package/dist/esm-node/error.js +14 -0
  7. package/dist/esm-node/index.js +44 -17
  8. package/dist/types/error.d.ts +6 -0
  9. package/dist/types/index.d.ts +21 -11
  10. package/package.json +19 -93
  11. package/dist/cjs/constants.js +0 -72
  12. package/dist/cjs/libs/context/context.js +0 -240
  13. package/dist/cjs/libs/context/index.js +0 -31
  14. package/dist/cjs/libs/hook-api/afterRenderForStream.js +0 -34
  15. package/dist/cjs/libs/hook-api/base.js +0 -107
  16. package/dist/cjs/libs/hook-api/index.js +0 -85
  17. package/dist/cjs/libs/hook-api/index.worker.js +0 -119
  18. package/dist/cjs/libs/hook-api/template.js +0 -74
  19. package/dist/cjs/libs/hook-api/templateForStream.js +0 -52
  20. package/dist/cjs/libs/loadConfig.js +0 -70
  21. package/dist/cjs/libs/metrics.js +0 -33
  22. package/dist/cjs/libs/preload/flushServerHeader.js +0 -49
  23. package/dist/cjs/libs/preload/index.js +0 -24
  24. package/dist/cjs/libs/preload/parseLinks.js +0 -124
  25. package/dist/cjs/libs/preload/shouldFlushServerHeader.js +0 -52
  26. package/dist/cjs/libs/preload/transformLinks2String.js +0 -150
  27. package/dist/cjs/libs/proxy.js +0 -99
  28. package/dist/cjs/libs/render/index.js +0 -97
  29. package/dist/cjs/libs/render/measure.js +0 -74
  30. package/dist/cjs/libs/render/ssr.js +0 -126
  31. package/dist/cjs/libs/render/ssrCache/cacheMod.js +0 -56
  32. package/dist/cjs/libs/render/ssrCache/index.js +0 -81
  33. package/dist/cjs/libs/render/ssrCache/manager.js +0 -104
  34. package/dist/cjs/libs/render/static.js +0 -72
  35. package/dist/cjs/libs/render/type.js +0 -33
  36. package/dist/cjs/libs/render/utils.js +0 -41
  37. package/dist/cjs/libs/reporter.js +0 -39
  38. package/dist/cjs/libs/route/index.js +0 -85
  39. package/dist/cjs/libs/route/matcher.js +0 -117
  40. package/dist/cjs/libs/route/route.js +0 -49
  41. package/dist/cjs/libs/serveFile.js +0 -84
  42. package/dist/cjs/libs/serverTiming.js +0 -44
  43. package/dist/cjs/renderHtml.js +0 -72
  44. package/dist/cjs/server/index.js +0 -229
  45. package/dist/cjs/server/modernServer.js +0 -532
  46. package/dist/cjs/server/modernServerSplit.js +0 -67
  47. package/dist/cjs/type.js +0 -16
  48. package/dist/cjs/utils.js +0 -164
  49. package/dist/cjs/workerServer.js +0 -264
  50. package/dist/esm/constants.js +0 -43
  51. package/dist/esm/libs/context/context.js +0 -292
  52. package/dist/esm/libs/context/index.js +0 -8
  53. package/dist/esm/libs/hook-api/afterRenderForStream.js +0 -33
  54. package/dist/esm/libs/hook-api/base.js +0 -108
  55. package/dist/esm/libs/hook-api/index.js +0 -55
  56. package/dist/esm/libs/hook-api/index.worker.js +0 -113
  57. package/dist/esm/libs/hook-api/route.js +0 -41
  58. package/dist/esm/libs/hook-api/template.js +0 -84
  59. package/dist/esm/libs/hook-api/templateForStream.js +0 -35
  60. package/dist/esm/libs/loadConfig.js +0 -36
  61. package/dist/esm/libs/metrics.js +0 -9
  62. package/dist/esm/libs/preload/flushServerHeader.js +0 -50
  63. package/dist/esm/libs/preload/index.js +0 -2
  64. package/dist/esm/libs/preload/parseLinks.js +0 -172
  65. package/dist/esm/libs/preload/shouldFlushServerHeader.js +0 -27
  66. package/dist/esm/libs/preload/transformLinks2String.js +0 -140
  67. package/dist/esm/libs/proxy.js +0 -160
  68. package/dist/esm/libs/render/index.js +0 -142
  69. package/dist/esm/libs/render/measure.js +0 -69
  70. package/dist/esm/libs/render/ssr.js +0 -129
  71. package/dist/esm/libs/render/ssrCache/cacheMod.js +0 -33
  72. package/dist/esm/libs/render/ssrCache/index.js +0 -146
  73. package/dist/esm/libs/render/ssrCache/manager.js +0 -159
  74. package/dist/esm/libs/render/static.js +0 -100
  75. package/dist/esm/libs/render/type.js +0 -9
  76. package/dist/esm/libs/render/utils.js +0 -16
  77. package/dist/esm/libs/reporter.js +0 -15
  78. package/dist/esm/libs/route/index.js +0 -116
  79. package/dist/esm/libs/route/matcher.js +0 -128
  80. package/dist/esm/libs/route/route.js +0 -26
  81. package/dist/esm/libs/serveFile.js +0 -68
  82. package/dist/esm/libs/serverTiming.js +0 -30
  83. package/dist/esm/renderHtml.js +0 -150
  84. package/dist/esm/server/index.js +0 -426
  85. package/dist/esm/server/modernServer.js +0 -1018
  86. package/dist/esm/server/modernServerSplit.js +0 -138
  87. package/dist/esm/type.js +0 -0
  88. package/dist/esm/utils.js +0 -103
  89. package/dist/esm/workerServer.js +0 -347
  90. package/dist/esm-node/constants.js +0 -43
  91. package/dist/esm-node/libs/context/context.js +0 -206
  92. package/dist/esm-node/libs/context/index.js +0 -6
  93. package/dist/esm-node/libs/hook-api/afterRenderForStream.js +0 -10
  94. package/dist/esm-node/libs/hook-api/base.js +0 -72
  95. package/dist/esm-node/libs/hook-api/index.js +0 -57
  96. package/dist/esm-node/libs/hook-api/index.worker.js +0 -92
  97. package/dist/esm-node/libs/hook-api/route.js +0 -24
  98. package/dist/esm-node/libs/hook-api/template.js +0 -49
  99. package/dist/esm-node/libs/hook-api/templateForStream.js +0 -28
  100. package/dist/esm-node/libs/loadConfig.js +0 -34
  101. package/dist/esm-node/libs/metrics.js +0 -9
  102. package/dist/esm-node/libs/preload/flushServerHeader.js +0 -25
  103. package/dist/esm-node/libs/preload/index.js +0 -2
  104. package/dist/esm-node/libs/preload/parseLinks.js +0 -90
  105. package/dist/esm-node/libs/preload/shouldFlushServerHeader.js +0 -27
  106. package/dist/esm-node/libs/preload/transformLinks2String.js +0 -126
  107. package/dist/esm-node/libs/proxy.js +0 -74
  108. package/dist/esm-node/libs/render/index.js +0 -63
  109. package/dist/esm-node/libs/render/measure.js +0 -49
  110. package/dist/esm-node/libs/render/ssr.js +0 -92
  111. package/dist/esm-node/libs/render/ssrCache/cacheMod.js +0 -22
  112. package/dist/esm-node/libs/render/ssrCache/index.js +0 -57
  113. package/dist/esm-node/libs/render/ssrCache/manager.js +0 -80
  114. package/dist/esm-node/libs/render/static.js +0 -38
  115. package/dist/esm-node/libs/render/type.js +0 -9
  116. package/dist/esm-node/libs/render/utils.js +0 -16
  117. package/dist/esm-node/libs/reporter.js +0 -15
  118. package/dist/esm-node/libs/route/index.js +0 -60
  119. package/dist/esm-node/libs/route/matcher.js +0 -93
  120. package/dist/esm-node/libs/route/route.js +0 -25
  121. package/dist/esm-node/libs/serveFile.js +0 -49
  122. package/dist/esm-node/libs/serverTiming.js +0 -20
  123. package/dist/esm-node/renderHtml.js +0 -80
  124. package/dist/esm-node/server/index.js +0 -195
  125. package/dist/esm-node/server/modernServer.js +0 -498
  126. package/dist/esm-node/server/modernServerSplit.js +0 -43
  127. package/dist/esm-node/type.js +0 -0
  128. package/dist/esm-node/utils.js +0 -132
  129. package/dist/esm-node/workerServer.js +0 -239
  130. package/dist/types/constants.d.ts +0 -30
  131. package/dist/types/libs/context/context.d.ts +0 -62
  132. package/dist/types/libs/context/index.d.ts +0 -7
  133. package/dist/types/libs/hook-api/afterRenderForStream.d.ts +0 -4
  134. package/dist/types/libs/hook-api/base.d.ts +0 -53
  135. package/dist/types/libs/hook-api/index.d.ts +0 -6
  136. package/dist/types/libs/hook-api/index.worker.d.ts +0 -19
  137. package/dist/types/libs/hook-api/route.d.ts +0 -9
  138. package/dist/types/libs/hook-api/template.d.ts +0 -22
  139. package/dist/types/libs/hook-api/templateForStream.d.ts +0 -8
  140. package/dist/types/libs/loadConfig.d.ts +0 -13
  141. package/dist/types/libs/metrics.d.ts +0 -3
  142. package/dist/types/libs/preload/flushServerHeader.d.ts +0 -14
  143. package/dist/types/libs/preload/index.d.ts +0 -2
  144. package/dist/types/libs/preload/parseLinks.d.ts +0 -13
  145. package/dist/types/libs/preload/shouldFlushServerHeader.d.ts +0 -3
  146. package/dist/types/libs/preload/transformLinks2String.d.ts +0 -3
  147. package/dist/types/libs/proxy.d.ts +0 -13
  148. package/dist/types/libs/render/index.d.ts +0 -21
  149. package/dist/types/libs/render/measure.d.ts +0 -10
  150. package/dist/types/libs/render/ssr.d.ts +0 -12
  151. package/dist/types/libs/render/ssrCache/cacheMod.d.ts +0 -8
  152. package/dist/types/libs/render/ssrCache/index.d.ts +0 -7
  153. package/dist/types/libs/render/ssrCache/manager.d.ts +0 -14
  154. package/dist/types/libs/render/static.d.ts +0 -3
  155. package/dist/types/libs/render/type.d.ts +0 -36
  156. package/dist/types/libs/render/utils.d.ts +0 -5
  157. package/dist/types/libs/reporter.d.ts +0 -2
  158. package/dist/types/libs/route/index.d.ts +0 -15
  159. package/dist/types/libs/route/matcher.d.ts +0 -15
  160. package/dist/types/libs/route/route.d.ts +0 -14
  161. package/dist/types/libs/serveFile.d.ts +0 -9
  162. package/dist/types/libs/serverTiming.d.ts +0 -13
  163. package/dist/types/renderHtml.d.ts +0 -23
  164. package/dist/types/server/index.d.ts +0 -55
  165. package/dist/types/server/modernServer.d.ts +0 -71
  166. package/dist/types/server/modernServerSplit.d.ts +0 -2
  167. package/dist/types/type.d.ts +0 -77
  168. package/dist/types/utils.d.ts +0 -24
  169. package/dist/types/workerServer.d.ts +0 -59
@@ -1,90 +0,0 @@
1
- import path from "path";
2
- import { NESTED_ROUTE_SPEC_FILE, ROUTE_MANIFEST_FILE, ROUTE_SPEC_FILE, fs } from "@modern-js/utils";
3
- import { parse as htmlParse } from "node-html-parser";
4
- import { matchRoutes } from "@modern-js/runtime-utils/remix-router";
5
- import { matchEntry } from "@modern-js/runtime-utils/node";
6
- async function parseLinks({ pathname, distDir, template }) {
7
- const links = await parseLinksFromRoutes(pathname, distDir);
8
- return links.concat(parseLinksFromHtml(template));
9
- }
10
- function parseLinksFromHtml(html) {
11
- const root = htmlParse(html);
12
- const scripts = root.querySelectorAll("script").filter((elem) => Boolean(elem.getAttribute("src")));
13
- const css = root.querySelectorAll("link").filter((elem) => {
14
- const href = elem.getAttribute("href");
15
- const rel = elem.getAttribute("rel");
16
- return href && rel === "stylesheet";
17
- });
18
- const images = root.querySelectorAll("img").filter((elem) => Boolean(elem.getAttribute("src")));
19
- return scripts.map((elem) => {
20
- const src = elem.getAttribute("src");
21
- return {
22
- uri: src,
23
- as: "script"
24
- };
25
- }).concat(css.map((elem) => {
26
- const href = elem.getAttribute("href");
27
- return {
28
- uri: href,
29
- as: "style"
30
- };
31
- })).concat(images.map((elem) => {
32
- const src = elem.getAttribute("src");
33
- return {
34
- uri: src,
35
- as: "image"
36
- };
37
- }));
38
- }
39
- async function parseLinksFromRoutes(pathname, distDir) {
40
- const noopLinks = [];
41
- const nestedRoutesSpec = path.join(distDir, NESTED_ROUTE_SPEC_FILE);
42
- const routesJsonPath = path.join(distDir, ROUTE_SPEC_FILE);
43
- const routeManifestPath = path.join(distDir, ROUTE_MANIFEST_FILE);
44
- if (!fs.existsSync(nestedRoutesSpec) || !fs.existsSync(routesJsonPath) || !fs.existsSync(routeManifestPath)) {
45
- return noopLinks;
46
- }
47
- const routesJson = await import(routesJsonPath);
48
- const serverRoutes = routesJson.routes;
49
- const entry = matchEntry(pathname, serverRoutes);
50
- if (entry) {
51
- var _routeAssets_entryName, _assets_filter, _assets_filter1;
52
- const routes = await import(nestedRoutesSpec);
53
- const { entryName } = entry;
54
- if (!entryName) {
55
- return noopLinks;
56
- }
57
- const entryRoutes = routes[entryName];
58
- if (!entryRoutes) {
59
- return noopLinks;
60
- }
61
- const routesManifest = await import(routeManifestPath);
62
- const { routeAssets } = routesManifest;
63
- const matches = matchRoutes(entryRoutes, pathname, entry.urlPath);
64
- const entryAssets = (_routeAssets_entryName = routeAssets[entryName]) === null || _routeAssets_entryName === void 0 ? void 0 : _routeAssets_entryName.assets;
65
- const assets = matches === null || matches === void 0 ? void 0 : matches.reduce((acc, match) => {
66
- const routeId = match.route.id;
67
- if (routeId) {
68
- const matchedManifest = routeAssets[routeId];
69
- const assets2 = matchedManifest === null || matchedManifest === void 0 ? void 0 : matchedManifest.assets;
70
- if (Array.isArray(assets2)) {
71
- acc.push(...assets2);
72
- }
73
- }
74
- return acc;
75
- }, []).concat(entryAssets || []);
76
- const cssLinks = assets === null || assets === void 0 ? void 0 : (_assets_filter = assets.filter((asset) => asset.endsWith(".css"))) === null || _assets_filter === void 0 ? void 0 : _assets_filter.map((uri) => ({
77
- uri,
78
- as: "style"
79
- }));
80
- const scriptLinks = assets === null || assets === void 0 ? void 0 : (_assets_filter1 = assets.filter((asset) => asset.endsWith(".js"))) === null || _assets_filter1 === void 0 ? void 0 : _assets_filter1.map((uri) => ({
81
- uri,
82
- as: "script"
83
- }));
84
- return (cssLinks || []).concat(scriptLinks || []);
85
- }
86
- return noopLinks;
87
- }
88
- export {
89
- parseLinks
90
- };
@@ -1,27 +0,0 @@
1
- function transformToRegExp(input) {
2
- if (typeof input === "string") {
3
- return new RegExp(input);
4
- }
5
- return input;
6
- }
7
- function shouldFlushServerHeader(serverConf, userAgent, disablePreload) {
8
- const { ssr: ssrConf } = serverConf || {};
9
- if (disablePreload) {
10
- return false;
11
- }
12
- if (typeof ssrConf === "object" && ssrConf.preload) {
13
- if (typeof ssrConf.preload === "object") {
14
- const { userAgentFilter } = ssrConf.preload;
15
- if (userAgentFilter && userAgent) {
16
- return !transformToRegExp(userAgentFilter).test(userAgent);
17
- }
18
- return true;
19
- }
20
- return true;
21
- }
22
- return false;
23
- }
24
- export {
25
- shouldFlushServerHeader,
26
- transformToRegExp
27
- };
@@ -1,126 +0,0 @@
1
- import { transformToRegExp } from "./shouldFlushServerHeader";
2
- function transformLinks2String(links, preload) {
3
- if (typeof preload === "boolean") {
4
- return transformLinkToString(dedup(links));
5
- }
6
- const { include, exclude, attributes } = preload;
7
- const resolveLinks = transformLinkToString(addAttributes(dedup(removeExclude(addInclude(links, include), exclude)), attributes));
8
- return resolveLinks;
9
- }
10
- function addInclude(links, include) {
11
- const images = [
12
- "gif",
13
- "jpg",
14
- "jpeg",
15
- "png",
16
- "webp",
17
- "bmp",
18
- "tiff",
19
- "anpg",
20
- "ico"
21
- ];
22
- const videos = [
23
- "mp4",
24
- "webm",
25
- "ogm",
26
- "ogv",
27
- "ogg"
28
- ];
29
- const fonts = [
30
- "woff",
31
- "woff2",
32
- "eot",
33
- "ttf",
34
- "otf"
35
- ];
36
- const includes = (include === null || include === void 0 ? void 0 : include.map((item) => {
37
- if (typeof item === "string") {
38
- const type = (() => {
39
- if (item.endsWith(".js")) {
40
- return "script";
41
- }
42
- if (item.endsWith(".css")) {
43
- return "style";
44
- }
45
- if (images.some((image) => item.endsWith(`.${image}`))) {
46
- return "image";
47
- }
48
- if (videos.some((video) => item.endsWith(`.${video}`))) {
49
- return "video";
50
- }
51
- if (fonts.some((font) => item.endsWith(`.${font}`))) {
52
- return "font";
53
- }
54
- })();
55
- return {
56
- uri: item,
57
- as: type
58
- };
59
- }
60
- return {
61
- uri: item.url,
62
- as: item.as,
63
- rel: item.rel
64
- };
65
- })) || [];
66
- return links.concat(includes);
67
- }
68
- function removeExclude(links, exclude) {
69
- return exclude ? links.filter(({ uri }) => !transformToRegExp(exclude).test(uri)) : links;
70
- }
71
- function addAttributes(links, attributes) {
72
- const parseAttributes = (_attributes) => {
73
- return Object.entries(_attributes || {}).reduce((results, [key, value]) => {
74
- if (typeof value === "boolean") {
75
- value && results.push(`; ${key}`);
76
- return results;
77
- }
78
- results.push(`; ${key}=${value}`);
79
- return results;
80
- }, []).join("");
81
- };
82
- return links.map((link) => {
83
- const { as } = link;
84
- if (as) {
85
- const attributesStr = (() => {
86
- const { style, script, image, font } = attributes || {};
87
- switch (as) {
88
- case "script":
89
- return parseAttributes(script);
90
- case "style":
91
- return parseAttributes(style);
92
- case "image":
93
- return parseAttributes(image);
94
- case "font":
95
- return parseAttributes(font);
96
- default:
97
- return "";
98
- }
99
- })();
100
- return {
101
- ...link,
102
- rest: attributesStr
103
- };
104
- }
105
- return link;
106
- });
107
- }
108
- function dedup(links) {
109
- const set = /* @__PURE__ */ new Set();
110
- return links.filter(({ uri }) => {
111
- if (set.has(uri)) {
112
- return false;
113
- }
114
- set.add(uri);
115
- return true;
116
- });
117
- }
118
- function transformLinkToString(links) {
119
- return links.map(({ uri, as, rel: originalRel, rest }) => {
120
- const rel = originalRel || "preload";
121
- return as ? `<${uri}>; rel=${rel}; as=${as}${rest || ""}` : `<${uri}>; rel=${rel}${rest || ""}`;
122
- }).join(", ");
123
- }
124
- export {
125
- transformLinks2String
126
- };
@@ -1,74 +0,0 @@
1
- import { HttpProxyMiddleware } from "http-proxy-middleware/dist/http-proxy-middleware";
2
- import { debug } from "../utils";
3
- function formatProxyOptions(proxyOptions) {
4
- const ret = [];
5
- if (Array.isArray(proxyOptions)) {
6
- ret.push(...proxyOptions);
7
- } else if ("target" in proxyOptions) {
8
- ret.push(proxyOptions);
9
- } else {
10
- for (const [context, options] of Object.entries(proxyOptions)) {
11
- const opts = {
12
- context,
13
- changeOrigin: true,
14
- logLevel: "warn"
15
- };
16
- if (typeof options === "string") {
17
- opts.target = options;
18
- } else {
19
- Object.assign(opts, options);
20
- }
21
- ret.push(opts);
22
- }
23
- }
24
- const handleError = (err, _req, _res, _target) => {
25
- console.error(err);
26
- };
27
- for (const opts of ret) {
28
- var _opts;
29
- var _onError;
30
- (_onError = (_opts = opts).onError) !== null && _onError !== void 0 ? _onError : _opts.onError = handleError;
31
- }
32
- return ret;
33
- }
34
- const createProxyHandler = (proxyOptions) => {
35
- debug("createProxyHandler", proxyOptions);
36
- const formattedOptionsList = formatProxyOptions(proxyOptions);
37
- const proxies = [];
38
- const handlers = [];
39
- for (const opts of formattedOptionsList) {
40
- const proxy = new HttpProxyMiddleware(opts.context, opts);
41
- const handler = async (ctx, next) => {
42
- const { req, res } = ctx;
43
- const bypassUrl = typeof opts.bypass === "function" ? opts.bypass(req, res, opts) : null;
44
- if (typeof bypassUrl === "boolean") {
45
- ctx.status = 404;
46
- next();
47
- } else if (typeof bypassUrl === "string") {
48
- ctx.url = bypassUrl;
49
- next();
50
- } else {
51
- proxy.middleware(req, res, next);
52
- }
53
- };
54
- proxies.push(proxy);
55
- handlers.push(handler);
56
- }
57
- const handleUpgrade = (server) => {
58
- for (const proxy of proxies) {
59
- const raw = proxy;
60
- if (raw.proxyOptions.ws === true && !raw.wsInternalSubscribed) {
61
- server.on("upgrade", raw.handleUpgrade);
62
- raw.wsInternalSubscribed = true;
63
- }
64
- }
65
- };
66
- return {
67
- handlers,
68
- handleUpgrade
69
- };
70
- };
71
- export {
72
- createProxyHandler,
73
- formatProxyOptions
74
- };
@@ -1,63 +0,0 @@
1
- import path from "path";
2
- import { cutNameByHyphen, mime } from "@modern-js/utils";
3
- import { fileReader } from "@modern-js/runtime-utils/fileReader";
4
- import { ERROR_DIGEST } from "../../constants";
5
- import { shouldFlushServerHeader } from "../preload/shouldFlushServerHeader";
6
- import { handleDirectory } from "./static";
7
- import * as ssr from "./ssr";
8
- import { injectServerData } from "./utils";
9
- const calcFallback = (metaName) => `x-${cutNameByHyphen(metaName)}-ssr-fallback`;
10
- const createRenderHandler = ({ distDir, staticGenerate, conf, forceCSR, nonce, ssrRender, metaName = "modern-js" }) => async function render({ ctx, route, runner }) {
11
- if (ctx.resHasHandled()) {
12
- return null;
13
- }
14
- const { entryPath, urlPath } = route;
15
- const entry = path.join(distDir, entryPath);
16
- if (!route.isSPA) {
17
- const result = await handleDirectory(ctx, entry, urlPath);
18
- return result;
19
- }
20
- const templatePath = entry;
21
- const content = await fileReader.readFile(templatePath);
22
- if (!content) {
23
- return null;
24
- }
25
- const useCSR = forceCSR && (ctx.query.csr || ctx.headers[calcFallback(metaName)]);
26
- if (route.isSSR && !useCSR) {
27
- try {
28
- const userAgent = ctx.getReqHeader("User-Agent");
29
- const disablePreload = Boolean(ctx.headers[`x-${cutNameByHyphen(metaName)}-disable-preload`]);
30
- if (shouldFlushServerHeader(conf.server, userAgent, disablePreload)) {
31
- const { flushServerHeader } = await import("../preload");
32
- flushServerHeader({
33
- serverConf: conf.server,
34
- ctx,
35
- distDir,
36
- template: content.toString(),
37
- headers: {
38
- "Content-Type": mime.contentType(path.extname(templatePath))
39
- }
40
- });
41
- }
42
- const ssrRenderOptions = {
43
- distDir,
44
- route,
45
- template: content.toString(),
46
- staticGenerate,
47
- nonce
48
- };
49
- const result = await (ssrRender ? ssrRender(ctx, ssrRenderOptions, runner) : ssr.render(ctx, ssrRenderOptions, runner));
50
- return result;
51
- } catch (err) {
52
- ctx.error(ERROR_DIGEST.ERENDER, err.stack || err.message);
53
- ctx.res.set(calcFallback(metaName), "1");
54
- }
55
- }
56
- return {
57
- content: route.entryName ? injectServerData(content.toString(), ctx) : content,
58
- contentType: mime.contentType(path.extname(templatePath))
59
- };
60
- };
61
- export {
62
- createRenderHandler
63
- };
@@ -1,49 +0,0 @@
1
- import { headersWithoutCookie } from "../../utils";
2
- const createMetrics = (context, metrics) => {
3
- const { entryName: entry, request } = context;
4
- const { pathname = "" } = request || {};
5
- const emitTimer = (name, cost, tags = {}) => {
6
- metrics.emitTimer(name, cost, void 0, {
7
- ...tags,
8
- pathname,
9
- entry
10
- });
11
- };
12
- const emitCounter = (name, counter, tags = {}) => {
13
- metrics.emitCounter(name, counter, void 0, {
14
- ...tags,
15
- pathname,
16
- entry
17
- });
18
- };
19
- return {
20
- emitTimer,
21
- emitCounter
22
- };
23
- };
24
- const createLogger = (serverContext, logger) => {
25
- const request = serverContext.request || {};
26
- const { headers = {}, pathname = "" } = request;
27
- const debug = (message, ...args) => {
28
- logger.debug(`SSR Debug - ${message}, req.url = %s`, ...args, pathname);
29
- };
30
- const info = (message, ...args) => {
31
- logger.info(`SSR Info - ${message}, req.url = %s`, ...args, pathname);
32
- };
33
- const error = (message, e) => {
34
- if (!e) {
35
- e = message;
36
- message = "";
37
- }
38
- logger.error(`SSR Error - ${message}, error = %s, req.url = %s, req.headers = %o`, e instanceof Error ? e.stack || e.message : e, pathname, headersWithoutCookie(headers));
39
- };
40
- return {
41
- error,
42
- info,
43
- debug
44
- };
45
- };
46
- export {
47
- createLogger,
48
- createMetrics
49
- };
@@ -1,92 +0,0 @@
1
- import path from "path";
2
- import { fs, mime, LOADABLE_STATS_FILE, ROUTE_MANIFEST_FILE, SERVER_RENDER_FUNCTION_NAME } from "@modern-js/utils";
3
- import * as isbot from "isbot";
4
- import { createAfterStreamingRenderContext } from "../hook-api";
5
- import { afterRenderInjectableStream } from "../hook-api/afterRenderForStream";
6
- import { createLogger, createMetrics } from "./measure";
7
- import { injectServerDataStream, injectServerData } from "./utils";
8
- import { ssrCache } from "./ssrCache";
9
- const render = async (ctx, renderOptions, runner) => {
10
- var _ctx_res;
11
- const { distDir, route, template, staticGenerate, enableUnsafeCtx = false, nonce } = renderOptions;
12
- const { urlPath, bundle, entryName } = route;
13
- const bundleJS = path.join(distDir, bundle);
14
- const loadableUri = path.join(distDir, LOADABLE_STATS_FILE);
15
- const loadableStats = fs.existsSync(loadableUri) ? require(loadableUri) : "";
16
- const routesManifestUri = path.join(distDir, ROUTE_MANIFEST_FILE);
17
- const routeManifest = fs.existsSync(routesManifestUri) ? require(routesManifestUri) : void 0;
18
- const isSpider = isbot.default(ctx.headers["user-agent"] || null);
19
- const context = {
20
- request: {
21
- baseUrl: urlPath,
22
- params: ctx.params,
23
- pathname: ctx.path,
24
- host: ctx.host,
25
- query: ctx.query,
26
- url: ctx.href,
27
- headers: ctx.headers
28
- },
29
- response: {
30
- setHeader: (key, value) => {
31
- return ctx.res.setHeader(key, value);
32
- },
33
- status: (code) => {
34
- ctx.res.statusCode = code;
35
- },
36
- locals: ((_ctx_res = ctx.res) === null || _ctx_res === void 0 ? void 0 : _ctx_res.locals) || {}
37
- },
38
- redirection: {},
39
- template,
40
- loadableStats,
41
- routeManifest,
42
- entryName,
43
- staticGenerate,
44
- logger: void 0,
45
- metrics: void 0,
46
- reporter: ctx.reporter,
47
- serverTiming: ctx.serverTiming,
48
- req: ctx.req,
49
- res: ctx.res,
50
- enableUnsafeCtx,
51
- isSpider,
52
- nonce
53
- };
54
- context.logger = createLogger(context, ctx.logger);
55
- context.metrics = createMetrics(context, ctx.metrics);
56
- runner.extendSSRContext(context);
57
- const bundleJSContent = await Promise.resolve(require(bundleJS));
58
- const serverRender = bundleJSContent[SERVER_RENDER_FUNCTION_NAME];
59
- const content = await ssrCache(ctx.req, serverRender, context);
60
- const { url, status = 302 } = context.redirection;
61
- if (url) {
62
- return {
63
- content: url,
64
- contentType: "",
65
- statusCode: status,
66
- redirect: true
67
- };
68
- }
69
- if (typeof content === "string") {
70
- return {
71
- content: injectServerData(content, ctx),
72
- contentType: mime.contentType("html")
73
- };
74
- } else {
75
- let contentStream = injectServerDataStream(content, ctx);
76
- const afterStreamingRenderContext = createAfterStreamingRenderContext(ctx, route);
77
- contentStream = contentStream.pipe(afterRenderInjectableStream((chunk) => {
78
- const context2 = afterStreamingRenderContext(chunk);
79
- return runner.afterStreamingRender(context2, {
80
- onLast: ({ chunk: chunk2 }) => chunk2
81
- });
82
- }));
83
- return {
84
- content: "",
85
- contentStream,
86
- contentType: mime.contentType("html")
87
- };
88
- }
89
- };
90
- export {
91
- render
92
- };
@@ -1,22 +0,0 @@
1
- import { _ as _define_property } from "@swc/helpers/_/_define_property";
2
- import path from "path";
3
- import { SERVER_DIR, requireExistModule } from "@modern-js/utils";
4
- const CACHE_FILENAME = "cache";
5
- class ServerCacheMod {
6
- loadServerCacheMod(pwd = process.cwd()) {
7
- const serverCacheFilepath = path.resolve(pwd, SERVER_DIR, CACHE_FILENAME);
8
- const mod = requireExistModule(serverCacheFilepath, {
9
- interop: false
10
- });
11
- this.customContainer = mod === null || mod === void 0 ? void 0 : mod.customContainer;
12
- this.cacheOption = mod === null || mod === void 0 ? void 0 : mod.cacheOption;
13
- }
14
- constructor() {
15
- _define_property(this, "customContainer", void 0);
16
- _define_property(this, "cacheOption", void 0);
17
- }
18
- }
19
- const cacheMod = new ServerCacheMod();
20
- export {
21
- cacheMod
22
- };
@@ -1,57 +0,0 @@
1
- import { Transform } from "stream";
2
- import { createMemoryStorage } from "@modern-js/runtime-utils/storer";
3
- import { cacheMod } from "./cacheMod";
4
- import { CacheManager } from "./manager";
5
- const cacheStorage = createMemoryStorage("__ssr__cache");
6
- async function ssrCache(req, render, ssrContext) {
7
- const { customContainer, cacheOption } = cacheMod;
8
- const cacheControl = await matchCacheControl(req, cacheOption);
9
- const cacheManager = new CacheManager(customContainer ? customContainer : cacheStorage);
10
- if (cacheControl) {
11
- return cacheManager.getCacheResult(req, cacheControl, render, ssrContext);
12
- } else {
13
- const renderResult = await render(ssrContext);
14
- if (typeof renderResult === "string") {
15
- return renderResult;
16
- } else {
17
- const stream = new Transform({
18
- write(chunk, _, callback) {
19
- this.push(chunk);
20
- callback();
21
- }
22
- });
23
- return renderResult(stream);
24
- }
25
- }
26
- }
27
- async function matchCacheControl(req, cacheOption) {
28
- if (!cacheOption) {
29
- return void 0;
30
- } else if (isCacheControl(cacheOption)) {
31
- return cacheOption;
32
- } else if (isCacheOptionProvider(cacheOption)) {
33
- return cacheOption(req);
34
- } else {
35
- const url = req.url;
36
- const options = Object.entries(cacheOption);
37
- for (const [key, option] of options) {
38
- if (key === "*" || new RegExp(key).test(url)) {
39
- if (typeof option === "function") {
40
- return option(req);
41
- } else {
42
- return option;
43
- }
44
- }
45
- }
46
- return void 0;
47
- }
48
- function isCacheOptionProvider(option) {
49
- return typeof option === "function";
50
- }
51
- function isCacheControl(option) {
52
- return typeof option === "object" && option !== null && "maxAge" in option;
53
- }
54
- }
55
- export {
56
- ssrCache
57
- };
@@ -1,80 +0,0 @@
1
- import { _ as _define_property } from "@swc/helpers/_/_define_property";
2
- import { Transform } from "stream";
3
- class CacheManager {
4
- async getCacheResult(req, cacheControl, render, ssrContext) {
5
- const key = this.computedKey(req, cacheControl);
6
- const value = await this.container.get(key);
7
- const { maxAge, staleWhileRevalidate } = cacheControl;
8
- const ttl = maxAge + staleWhileRevalidate;
9
- if (value) {
10
- const cache = JSON.parse(value);
11
- const interval = Date.now() - cache.cursor;
12
- if (interval <= maxAge) {
13
- return cache.val;
14
- } else if (interval <= staleWhileRevalidate + maxAge) {
15
- this.processCache(key, render, ssrContext, ttl);
16
- return cache.val;
17
- } else {
18
- return this.processCache(key, render, ssrContext, ttl);
19
- }
20
- } else {
21
- return this.processCache(key, render, ssrContext, ttl);
22
- }
23
- }
24
- async processCache(key, render, ssrContext, ttl) {
25
- const renderResult = await render(ssrContext);
26
- if (typeof renderResult === "string") {
27
- const current = Date.now();
28
- const cache = {
29
- val: renderResult,
30
- cursor: current
31
- };
32
- await this.container.set(key, JSON.stringify(cache), {
33
- ttl
34
- });
35
- return renderResult;
36
- } else {
37
- let html;
38
- const stream = new Transform({
39
- write(chunk, _, callback) {
40
- html += chunk.toString();
41
- this.push(chunk);
42
- callback();
43
- }
44
- });
45
- stream.on("close", () => {
46
- const current = Date.now();
47
- const cache = {
48
- val: html,
49
- cursor: current
50
- };
51
- this.container.set(key, JSON.stringify(cache), {
52
- ttl
53
- });
54
- });
55
- return renderResult(stream);
56
- }
57
- }
58
- computedKey(req, cacheControl) {
59
- const { url } = req;
60
- const [pathname] = url.split("?");
61
- const { customKey } = cacheControl;
62
- const defaultKey = pathname.replace(/.+\/+$/, "");
63
- if (customKey) {
64
- if (typeof customKey === "string") {
65
- return customKey;
66
- } else {
67
- return customKey(defaultKey);
68
- }
69
- } else {
70
- return defaultKey;
71
- }
72
- }
73
- constructor(container) {
74
- _define_property(this, "container", void 0);
75
- this.container = container;
76
- }
77
- }
78
- export {
79
- CacheManager
80
- };