vite-react-ssg 0.0.2 → 0.1.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/README.md +124 -3
- package/dist/index.cjs +37 -2
- package/dist/index.d.ts +9 -3
- package/dist/index.mjs +44 -10
- package/dist/node/cli.cjs +29 -5
- package/dist/node/cli.mjs +28 -4
- package/dist/node.cjs +5 -2
- package/dist/node.d.ts +4 -2
- package/dist/node.mjs +3 -1
- package/dist/shared/{vite-react-ssg.f66e4ba5.mjs → vite-react-ssg.7ee042ba.mjs} +295 -62
- package/dist/shared/{vite-react-ssg.0e1b881e.cjs → vite-react-ssg.823b31c9.cjs} +295 -60
- package/dist/{types-82f34756.d.ts → types-25b96ed0.d.ts} +8 -0
- package/package.json +3 -1
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { join, isAbsolute, parse, dirname } from 'node:path';
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { gray, yellow, blue, dim, cyan, red, green } from 'kolorist';
|
|
3
|
+
import { gray, yellow, blue, dim, cyan, red, green, bold, reset, bgLightCyan } from 'kolorist';
|
|
4
4
|
import fs from 'fs-extra';
|
|
5
|
-
import { resolveConfig, build as build$1, mergeConfig } from 'vite';
|
|
5
|
+
import { resolveConfig, build as build$1, mergeConfig, createServer, version as version$1 } from 'vite';
|
|
6
6
|
import { JSDOM } from 'jsdom';
|
|
7
7
|
import { S as SiteMetadataDefaults, s as serializeState } from './vite-react-ssg.9d005d5e.mjs';
|
|
8
|
+
import express from 'express';
|
|
9
|
+
import { readFileSync } from 'node:fs';
|
|
8
10
|
import React from 'react';
|
|
9
11
|
import { HelmetProvider } from 'react-helmet-async';
|
|
10
12
|
import { createStaticHandler, createStaticRouter, StaticRouterProvider } from 'react-router-dom/server.js';
|
|
@@ -868,9 +870,10 @@ function routesToPaths(routes) {
|
|
|
868
870
|
pathToEntry[path] = /* @__PURE__ */ new Set([entry]);
|
|
869
871
|
}
|
|
870
872
|
if (!routes)
|
|
871
|
-
return { paths: ["/"] };
|
|
873
|
+
return { paths: ["/"], pathToEntry };
|
|
872
874
|
const paths = /* @__PURE__ */ new Set();
|
|
873
875
|
const getPaths = (routes2, prefix = "") => {
|
|
876
|
+
const parentPath = prefix;
|
|
874
877
|
prefix = prefix.replace(/\/$/g, "");
|
|
875
878
|
for (const route of routes2) {
|
|
876
879
|
let path = route.path;
|
|
@@ -878,6 +881,10 @@ function routesToPaths(routes) {
|
|
|
878
881
|
path = prefix && !route.path.startsWith("/") ? `${prefix}${route.path ? `/${route.path}` : ""}` : route.path;
|
|
879
882
|
paths.add(path);
|
|
880
883
|
addEntry(path, route.entry);
|
|
884
|
+
if (pathToEntry[parentPath]) {
|
|
885
|
+
const pathCopy = path;
|
|
886
|
+
pathToEntry[parentPath].forEach((entry) => addEntry(pathCopy, entry));
|
|
887
|
+
}
|
|
881
888
|
}
|
|
882
889
|
if (route.index)
|
|
883
890
|
addEntry(prefix, route.entry);
|
|
@@ -888,6 +895,39 @@ function routesToPaths(routes) {
|
|
|
888
895
|
getPaths(routes);
|
|
889
896
|
return { paths: Array.from(paths), pathToEntry };
|
|
890
897
|
}
|
|
898
|
+
function createFetchRequest(req) {
|
|
899
|
+
const origin = `${req.protocol}://${req.get("host")}`;
|
|
900
|
+
const url = new URL(req.originalUrl || req.url, origin);
|
|
901
|
+
const controller = new AbortController();
|
|
902
|
+
req.on("close", () => controller.abort());
|
|
903
|
+
const headers = new Headers();
|
|
904
|
+
for (const [key, values] of Object.entries(req.headers)) {
|
|
905
|
+
if (values) {
|
|
906
|
+
if (Array.isArray(values)) {
|
|
907
|
+
for (const value of values)
|
|
908
|
+
headers.append(key, value);
|
|
909
|
+
} else {
|
|
910
|
+
headers.set(key, values);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
const init = {
|
|
915
|
+
method: req.method,
|
|
916
|
+
headers,
|
|
917
|
+
signal: controller.signal
|
|
918
|
+
};
|
|
919
|
+
if (req.method !== "GET" && req.method !== "HEAD")
|
|
920
|
+
init.body = req.body;
|
|
921
|
+
return new Request(url.href, init);
|
|
922
|
+
}
|
|
923
|
+
async function resolveAlias(config, entry) {
|
|
924
|
+
const resolver = config.createResolver();
|
|
925
|
+
const result = await resolver(entry, config.root);
|
|
926
|
+
return result || join(config.root, entry);
|
|
927
|
+
}
|
|
928
|
+
const { version } = JSON.parse(
|
|
929
|
+
readFileSync(new URL("../../package.json", import.meta.url)).toString()
|
|
930
|
+
);
|
|
891
931
|
|
|
892
932
|
async function getCritters(outDir, options = {}) {
|
|
893
933
|
try {
|
|
@@ -958,17 +998,18 @@ async function render(routes, request) {
|
|
|
958
998
|
throw context;
|
|
959
999
|
const router = createStaticRouter(dataRoutes, context);
|
|
960
1000
|
const app = /* @__PURE__ */ React.createElement(HelmetProvider, { context: helmetContext }, /* @__PURE__ */ React.createElement(SiteMetadataDefaults, null), /* @__PURE__ */ React.createElement(StaticRouterProvider, { router, context }));
|
|
961
|
-
const
|
|
1001
|
+
const appHTML = await renderStaticApp(app);
|
|
962
1002
|
const { helmet } = helmetContext;
|
|
963
|
-
helmet.htmlAttributes.toString();
|
|
964
|
-
helmet.bodyAttributes.toString();
|
|
965
|
-
[
|
|
1003
|
+
const htmlAttributes = helmet.htmlAttributes.toString();
|
|
1004
|
+
const bodyAttributes = helmet.bodyAttributes.toString();
|
|
1005
|
+
const metaStrings = [
|
|
966
1006
|
helmet.title.toString(),
|
|
967
1007
|
helmet.meta.toString(),
|
|
968
1008
|
helmet.link.toString(),
|
|
969
1009
|
helmet.script.toString()
|
|
970
1010
|
];
|
|
971
|
-
|
|
1011
|
+
const metaAttributes = metaStrings.filter(Boolean);
|
|
1012
|
+
return { appHTML, htmlAttributes, bodyAttributes, metaAttributes };
|
|
972
1013
|
}
|
|
973
1014
|
|
|
974
1015
|
function renderPreloadLinks(document, modules, ssrManifest) {
|
|
@@ -1004,7 +1045,7 @@ function renderPreloadLink(document, file) {
|
|
|
1004
1045
|
});
|
|
1005
1046
|
}
|
|
1006
1047
|
}
|
|
1007
|
-
function createLink(document) {
|
|
1048
|
+
function createLink$1(document) {
|
|
1008
1049
|
return document.createElement("link");
|
|
1009
1050
|
}
|
|
1010
1051
|
function setAttrs(el, attrs) {
|
|
@@ -1016,11 +1057,68 @@ function appendLink(document, attrs) {
|
|
|
1016
1057
|
const exits = document.head.querySelector(`link[href='${attrs.file}']`);
|
|
1017
1058
|
if (exits)
|
|
1018
1059
|
return;
|
|
1019
|
-
const link = createLink(document);
|
|
1060
|
+
const link = createLink$1(document);
|
|
1020
1061
|
setAttrs(link, attrs);
|
|
1021
1062
|
document.head.appendChild(link);
|
|
1022
1063
|
}
|
|
1023
1064
|
|
|
1065
|
+
async function renderHTML({
|
|
1066
|
+
rootContainerId,
|
|
1067
|
+
indexHTML,
|
|
1068
|
+
appHTML,
|
|
1069
|
+
metaAttributes,
|
|
1070
|
+
bodyAttributes,
|
|
1071
|
+
htmlAttributes,
|
|
1072
|
+
initialState
|
|
1073
|
+
}) {
|
|
1074
|
+
const stateScript = initialState ? `
|
|
1075
|
+
<script>window.__INITIAL_STATE__=${initialState}<\/script>` : "";
|
|
1076
|
+
const headStartTag = "<head>";
|
|
1077
|
+
const metaTags = metaAttributes.join("");
|
|
1078
|
+
indexHTML = indexHTML.replace(headStartTag, headStartTag + metaTags);
|
|
1079
|
+
const bodyStartTag = "<body";
|
|
1080
|
+
indexHTML = indexHTML.replace(bodyStartTag, `${bodyStartTag} ${bodyAttributes}`);
|
|
1081
|
+
const htmlStartTag = "<html";
|
|
1082
|
+
indexHTML = indexHTML.replace(htmlStartTag, `${htmlStartTag} ${htmlAttributes}`);
|
|
1083
|
+
const container = `<div id="${rootContainerId}"></div>`;
|
|
1084
|
+
if (indexHTML.includes(container)) {
|
|
1085
|
+
return indexHTML.replace(
|
|
1086
|
+
container,
|
|
1087
|
+
`<div id="${rootContainerId}" data-server-rendered="true">${appHTML}</div>${stateScript}`
|
|
1088
|
+
);
|
|
1089
|
+
}
|
|
1090
|
+
const html5Parser = await import('html5parser');
|
|
1091
|
+
const ast = html5Parser.parse(indexHTML);
|
|
1092
|
+
let renderedOutput;
|
|
1093
|
+
html5Parser.walk(ast, {
|
|
1094
|
+
enter: (node) => {
|
|
1095
|
+
if (!renderedOutput && node?.type === html5Parser.SyntaxKind.Tag && Array.isArray(node.attributes) && node.attributes.length > 0 && node.attributes.some((attr) => attr.name.value === "id" && attr.value?.value === rootContainerId)) {
|
|
1096
|
+
const attributesStringified = [...node.attributes.map(({ name: { value: name }, value }) => `${name}="${value.value}"`)].join(" ");
|
|
1097
|
+
const indexHTMLBefore = indexHTML.slice(0, node.start);
|
|
1098
|
+
const indexHTMLAfter = indexHTML.slice(node.end);
|
|
1099
|
+
renderedOutput = `${indexHTMLBefore}<${node.name} ${attributesStringified} data-server-rendered="true">${appHTML}</${node.name}>${stateScript}${indexHTMLAfter}`;
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
});
|
|
1103
|
+
if (!renderedOutput)
|
|
1104
|
+
throw new Error(`Could not find a tag with id="${rootContainerId}" to replace it with server-side rendered HTML`);
|
|
1105
|
+
return renderedOutput;
|
|
1106
|
+
}
|
|
1107
|
+
async function detectEntry(root) {
|
|
1108
|
+
const scriptSrcReg = /<script(?:.*?)src=["'](.+?)["'](?!<)(?:.*)\>(?:[\n\r\s]*?)(?:<\/script>)/img;
|
|
1109
|
+
const html = await fs.readFile(join(root, "index.html"), "utf-8");
|
|
1110
|
+
const scripts = [...html.matchAll(scriptSrcReg)];
|
|
1111
|
+
const [, entry] = scripts.find((matchResult) => {
|
|
1112
|
+
const [script] = matchResult;
|
|
1113
|
+
const [, scriptType] = script.match(/.*\stype=(?:'|")?([^>'"\s]+)/i) || [];
|
|
1114
|
+
return scriptType === "module";
|
|
1115
|
+
}) || [];
|
|
1116
|
+
return entry || "src/main.ts";
|
|
1117
|
+
}
|
|
1118
|
+
function createLink(href) {
|
|
1119
|
+
return `<link rel="stylesheet" href="${href}">`;
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1024
1122
|
function DefaultIncludedRoutes(paths, _routes) {
|
|
1025
1123
|
return paths.filter((i) => !i.includes(":") && !i.includes("*"));
|
|
1026
1124
|
}
|
|
@@ -1112,18 +1210,21 @@ async function build(ssgOptions = {}, viteConfig = {}) {
|
|
|
1112
1210
|
try {
|
|
1113
1211
|
const appCtx = await createRoot(false, route);
|
|
1114
1212
|
const { routes: routes2, initialState, triggerOnSSRAppRendered, transformState = serializeState } = appCtx;
|
|
1115
|
-
const transformedIndexHTML = await onBeforePageRender?.(route, indexHTML, appCtx);
|
|
1213
|
+
const transformedIndexHTML = await onBeforePageRender?.(route, indexHTML, appCtx) || indexHTML;
|
|
1116
1214
|
const url = new URL(route, "http://vite-react-ssg.com");
|
|
1117
1215
|
url.search = "";
|
|
1118
1216
|
url.hash = "";
|
|
1119
1217
|
url.pathname = route;
|
|
1120
1218
|
const request = new Request(url.href);
|
|
1121
|
-
const appHTML = await render([...routes2], request);
|
|
1219
|
+
const { appHTML, bodyAttributes, htmlAttributes, metaAttributes } = await render([...routes2], request);
|
|
1122
1220
|
await triggerOnSSRAppRendered?.(route, appHTML, appCtx);
|
|
1123
1221
|
const renderedHTML = await renderHTML({
|
|
1124
1222
|
rootContainerId,
|
|
1125
1223
|
appHTML,
|
|
1126
|
-
indexHTML,
|
|
1224
|
+
indexHTML: transformedIndexHTML,
|
|
1225
|
+
metaAttributes,
|
|
1226
|
+
bodyAttributes,
|
|
1227
|
+
htmlAttributes,
|
|
1127
1228
|
initialState: null
|
|
1128
1229
|
});
|
|
1129
1230
|
const jsdom = new JSDOM(renderedHTML);
|
|
@@ -1164,59 +1265,11 @@ ${gray("[vite-react-ssg]")} ${green("Build finished.")}`);
|
|
|
1164
1265
|
}, waitInSeconds * 1e3);
|
|
1165
1266
|
timeout.unref();
|
|
1166
1267
|
}
|
|
1167
|
-
async function detectEntry(root) {
|
|
1168
|
-
const scriptSrcReg = /<script(?:.*?)src=["'](.+?)["'](?!<)(?:.*)\>(?:[\n\r\s]*?)(?:<\/script>)/img;
|
|
1169
|
-
const html = await fs.readFile(join(root, "index.html"), "utf-8");
|
|
1170
|
-
const scripts = [...html.matchAll(scriptSrcReg)];
|
|
1171
|
-
const [, entry] = scripts.find((matchResult) => {
|
|
1172
|
-
const [script] = matchResult;
|
|
1173
|
-
const [, scriptType] = script.match(/.*\stype=(?:'|")?([^>'"\s]+)/i) || [];
|
|
1174
|
-
return scriptType === "module";
|
|
1175
|
-
}) || [];
|
|
1176
|
-
return entry || "src/main.ts";
|
|
1177
|
-
}
|
|
1178
|
-
async function resolveAlias(config, entry) {
|
|
1179
|
-
const resolver = config.createResolver();
|
|
1180
|
-
const result = await resolver(entry, config.root);
|
|
1181
|
-
return result || join(config.root, entry);
|
|
1182
|
-
}
|
|
1183
1268
|
function rewriteScripts(indexHTML, mode) {
|
|
1184
1269
|
if (!mode || mode === "sync")
|
|
1185
1270
|
return indexHTML;
|
|
1186
1271
|
return indexHTML.replace(/<script type="module" /g, `<script type="module" ${mode} `);
|
|
1187
1272
|
}
|
|
1188
|
-
async function renderHTML({
|
|
1189
|
-
rootContainerId,
|
|
1190
|
-
indexHTML,
|
|
1191
|
-
appHTML,
|
|
1192
|
-
initialState
|
|
1193
|
-
}) {
|
|
1194
|
-
const stateScript = initialState ? `
|
|
1195
|
-
<script>window.__INITIAL_STATE__=${initialState}<\/script>` : "";
|
|
1196
|
-
const container = `<div id="${rootContainerId}"></div>`;
|
|
1197
|
-
if (indexHTML.includes(container)) {
|
|
1198
|
-
return indexHTML.replace(
|
|
1199
|
-
container,
|
|
1200
|
-
`<div id="${rootContainerId}" data-server-rendered="true">${appHTML}</div>${stateScript}`
|
|
1201
|
-
);
|
|
1202
|
-
}
|
|
1203
|
-
const html5Parser = await import('html5parser');
|
|
1204
|
-
const ast = html5Parser.parse(indexHTML);
|
|
1205
|
-
let renderedOutput;
|
|
1206
|
-
html5Parser.walk(ast, {
|
|
1207
|
-
enter: (node) => {
|
|
1208
|
-
if (!renderedOutput && node?.type === html5Parser.SyntaxKind.Tag && Array.isArray(node.attributes) && node.attributes.length > 0 && node.attributes.some((attr) => attr.name.value === "id" && attr.value?.value === rootContainerId)) {
|
|
1209
|
-
const attributesStringified = [...node.attributes.map(({ name: { value: name }, value }) => `${name}="${value.value}"`)].join(" ");
|
|
1210
|
-
const indexHTMLBefore = indexHTML.slice(0, node.start);
|
|
1211
|
-
const indexHTMLAfter = indexHTML.slice(node.end);
|
|
1212
|
-
renderedOutput = `${indexHTMLBefore}<${node.name} ${attributesStringified} data-server-rendered="true">${appHTML}</${node.name}>${stateScript}${indexHTMLAfter}`;
|
|
1213
|
-
}
|
|
1214
|
-
}
|
|
1215
|
-
});
|
|
1216
|
-
if (!renderedOutput)
|
|
1217
|
-
throw new Error(`Could not find a tag with id="${rootContainerId}" to replace it with server-side rendered HTML`);
|
|
1218
|
-
return renderedOutput;
|
|
1219
|
-
}
|
|
1220
1273
|
async function formatHtml(html, formatting) {
|
|
1221
1274
|
if (formatting === "minify") {
|
|
1222
1275
|
const htmlMinifier = await import('html-minifier');
|
|
@@ -1252,4 +1305,184 @@ function collectModules(manifest, entry, mods = /* @__PURE__ */ new Set()) {
|
|
|
1252
1305
|
return mods;
|
|
1253
1306
|
}
|
|
1254
1307
|
|
|
1255
|
-
|
|
1308
|
+
const SHORTCUTS = [
|
|
1309
|
+
{
|
|
1310
|
+
key: "u",
|
|
1311
|
+
description: "show server url",
|
|
1312
|
+
action(vite, _) {
|
|
1313
|
+
vite.config.logger.info("");
|
|
1314
|
+
printServerInfo(vite, true);
|
|
1315
|
+
}
|
|
1316
|
+
},
|
|
1317
|
+
{
|
|
1318
|
+
key: "c",
|
|
1319
|
+
description: "clear console",
|
|
1320
|
+
action(vite, _) {
|
|
1321
|
+
vite.config.logger.clearScreen("error");
|
|
1322
|
+
}
|
|
1323
|
+
},
|
|
1324
|
+
{
|
|
1325
|
+
key: "q",
|
|
1326
|
+
description: "quit",
|
|
1327
|
+
action(_, server) {
|
|
1328
|
+
server.close(() => process.exit());
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
];
|
|
1332
|
+
function bindShortcuts(viteServer, server) {
|
|
1333
|
+
if (!process.stdin.isTTY || process.env.CI)
|
|
1334
|
+
return;
|
|
1335
|
+
viteServer.config.logger.info(
|
|
1336
|
+
dim(green(" \u279C")) + dim(" press ") + bold("h") + dim(" to show help")
|
|
1337
|
+
);
|
|
1338
|
+
const shortcuts = SHORTCUTS;
|
|
1339
|
+
let actionRunning = false;
|
|
1340
|
+
const onInput = async (input) => {
|
|
1341
|
+
if (input === "" || input === "") {
|
|
1342
|
+
try {
|
|
1343
|
+
await server.close();
|
|
1344
|
+
} finally {
|
|
1345
|
+
process.exit(1);
|
|
1346
|
+
}
|
|
1347
|
+
return;
|
|
1348
|
+
}
|
|
1349
|
+
if (actionRunning)
|
|
1350
|
+
return;
|
|
1351
|
+
if (input === "h") {
|
|
1352
|
+
viteServer.config.logger.info(
|
|
1353
|
+
[
|
|
1354
|
+
"",
|
|
1355
|
+
bold(" Shortcuts"),
|
|
1356
|
+
...shortcuts.map(
|
|
1357
|
+
(shortcut2) => dim(" press ") + bold(shortcut2.key) + dim(` to ${shortcut2.description}`)
|
|
1358
|
+
)
|
|
1359
|
+
].join("\n")
|
|
1360
|
+
);
|
|
1361
|
+
}
|
|
1362
|
+
const shortcut = shortcuts.find((shortcut2) => shortcut2.key === input);
|
|
1363
|
+
if (!shortcut)
|
|
1364
|
+
return;
|
|
1365
|
+
actionRunning = true;
|
|
1366
|
+
await shortcut.action(viteServer, server);
|
|
1367
|
+
actionRunning = false;
|
|
1368
|
+
};
|
|
1369
|
+
process.stdin.setRawMode(true);
|
|
1370
|
+
process.stdin.on("data", onInput).setEncoding("utf8").resume();
|
|
1371
|
+
server.on("close", () => {
|
|
1372
|
+
process.stdin.off("data", onInput).pause();
|
|
1373
|
+
});
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
async function dev(ssgOptions = {}, viteConfig = {}) {
|
|
1377
|
+
const mode = process.env.MODE || process.env.NODE_ENV || ssgOptions.mode || "development";
|
|
1378
|
+
const config = await resolveConfig(viteConfig, "serve", mode, mode);
|
|
1379
|
+
const cwd = process.cwd();
|
|
1380
|
+
const root = config.root || cwd;
|
|
1381
|
+
const {
|
|
1382
|
+
entry = await detectEntry(root),
|
|
1383
|
+
onBeforePageRender,
|
|
1384
|
+
onPageRendered,
|
|
1385
|
+
rootContainerId = "root"
|
|
1386
|
+
} = Object.assign({}, config.ssgOptions || {}, ssgOptions);
|
|
1387
|
+
const ssrEntry = await resolveAlias(config, entry);
|
|
1388
|
+
const template = await fs.readFile(join(root, "index.html"), "utf-8");
|
|
1389
|
+
let viteServer;
|
|
1390
|
+
globalThis.__ssr_start_time = performance.now();
|
|
1391
|
+
createServer$1().then((app) => {
|
|
1392
|
+
const port = viteServer.config.server.port || 5173;
|
|
1393
|
+
const server = app.listen(port, () => {
|
|
1394
|
+
printServerInfo(viteServer);
|
|
1395
|
+
bindShortcuts(viteServer, server);
|
|
1396
|
+
});
|
|
1397
|
+
});
|
|
1398
|
+
async function createServer$1() {
|
|
1399
|
+
process.env.__DEV_MODE_SSR = "true";
|
|
1400
|
+
const app = express();
|
|
1401
|
+
viteServer = await createServer({
|
|
1402
|
+
// ...options,
|
|
1403
|
+
server: { middlewareMode: true },
|
|
1404
|
+
appType: "custom"
|
|
1405
|
+
});
|
|
1406
|
+
app.use(viteServer.middlewares);
|
|
1407
|
+
app.use("*", async (req, res) => {
|
|
1408
|
+
try {
|
|
1409
|
+
const url = req.originalUrl;
|
|
1410
|
+
const indexHTML = await viteServer.transformIndexHtml(url, template);
|
|
1411
|
+
const createRoot = await viteServer.ssrLoadModule(ssrEntry).then((m) => m.createRoot);
|
|
1412
|
+
const appCtx = await createRoot(false, url);
|
|
1413
|
+
const { routes } = appCtx;
|
|
1414
|
+
const transformedIndexHTML = await onBeforePageRender?.(url, indexHTML, appCtx) || indexHTML;
|
|
1415
|
+
const { appHTML, bodyAttributes, htmlAttributes, metaAttributes } = await render([...routes], createFetchRequest(req));
|
|
1416
|
+
const mod = await viteServer.moduleGraph.getModuleByUrl(entry);
|
|
1417
|
+
const assetsUrls = /* @__PURE__ */ new Set();
|
|
1418
|
+
const collectAssets = async (mod2) => {
|
|
1419
|
+
if (!mod2?.ssrTransformResult)
|
|
1420
|
+
return;
|
|
1421
|
+
const { deps = [], dynamicDeps = [] } = mod2?.ssrTransformResult;
|
|
1422
|
+
const allDeps = [...deps, ...dynamicDeps];
|
|
1423
|
+
for (const dep of allDeps) {
|
|
1424
|
+
if (dep.endsWith(".css")) {
|
|
1425
|
+
assetsUrls.add(dep);
|
|
1426
|
+
} else if (dep.endsWith(".ts") || dep.endsWith(".tsx")) {
|
|
1427
|
+
const depModule = await viteServer.moduleGraph.getModuleByUrl(dep);
|
|
1428
|
+
depModule && await collectAssets(depModule);
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
};
|
|
1432
|
+
await collectAssets(mod);
|
|
1433
|
+
const preloadLink = [...assetsUrls].map((item) => createLink(item));
|
|
1434
|
+
metaAttributes.push(...preloadLink);
|
|
1435
|
+
const renderedHTML = await renderHTML({
|
|
1436
|
+
rootContainerId,
|
|
1437
|
+
appHTML,
|
|
1438
|
+
indexHTML: transformedIndexHTML,
|
|
1439
|
+
metaAttributes,
|
|
1440
|
+
bodyAttributes,
|
|
1441
|
+
htmlAttributes,
|
|
1442
|
+
initialState: null
|
|
1443
|
+
});
|
|
1444
|
+
const transformed = await onPageRendered?.(url, renderedHTML, appCtx) || renderedHTML;
|
|
1445
|
+
res.status(200).set({ "Content-Type": "text/html" }).end(transformed);
|
|
1446
|
+
} catch (e) {
|
|
1447
|
+
viteServer.ssrFixStacktrace(e);
|
|
1448
|
+
console.error(`[vite-react-ssg] error: ${e.stack}`);
|
|
1449
|
+
res.status(500).end(e.stack);
|
|
1450
|
+
}
|
|
1451
|
+
});
|
|
1452
|
+
return app;
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
async function printServerInfo(server, onlyUrl = false) {
|
|
1456
|
+
const info = server.config.logger.info;
|
|
1457
|
+
const port = server.config.server.port || 5173;
|
|
1458
|
+
const url = `http://localhost:${port}/`;
|
|
1459
|
+
if (!onlyUrl) {
|
|
1460
|
+
let ssrReadyMessage = " -- SSR";
|
|
1461
|
+
if (globalThis.__ssr_start_time) {
|
|
1462
|
+
ssrReadyMessage += ` ready in ${reset(bold(`${Math.round(
|
|
1463
|
+
// @ts-expect-error global var
|
|
1464
|
+
performance.now() - globalThis.__ssr_start_time
|
|
1465
|
+
)}ms`))}`;
|
|
1466
|
+
}
|
|
1467
|
+
info(
|
|
1468
|
+
`
|
|
1469
|
+
${bgLightCyan(` VITE-REACT-SSG v${version} `)}`,
|
|
1470
|
+
{ clear: !server.config.logger.hasWarned }
|
|
1471
|
+
);
|
|
1472
|
+
info(
|
|
1473
|
+
`${cyan(`
|
|
1474
|
+
VITE v${version$1}`) + dim(ssrReadyMessage)}
|
|
1475
|
+
`
|
|
1476
|
+
);
|
|
1477
|
+
}
|
|
1478
|
+
info(
|
|
1479
|
+
green(" dev server running at:")
|
|
1480
|
+
);
|
|
1481
|
+
printUrls(url, info);
|
|
1482
|
+
}
|
|
1483
|
+
function printUrls(url, info) {
|
|
1484
|
+
const colorUrl = (url2) => cyan(url2.replace(/:(\d+)\//, (_, port) => `:${bold(port)}/`));
|
|
1485
|
+
info(` ${green("\u279C")} ${bold("Local")}: ${colorUrl(url)}`);
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
export { build as b, dev as d };
|