vite-react-ssg 0.0.3 → 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/LICENSE +21 -21
- package/README.md +292 -238
- package/bin/vite-react-ssg.js +3 -3
- package/dist/chunks/jsdomGlobal.cjs +79 -79
- package/dist/chunks/jsdomGlobal.mjs +79 -79
- 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.524ba00d.mjs → vite-react-ssg.7ee042ba.mjs} +279 -65
- package/dist/shared/{vite-react-ssg.a5dfecac.cjs → vite-react-ssg.823b31c9.cjs} +279 -63
- package/dist/{types-82f34756.d.ts → types-25b96ed0.d.ts} +8 -0
- package/package.json +4 -2
|
@@ -7,6 +7,8 @@ const fs = require('fs-extra');
|
|
|
7
7
|
const vite = require('vite');
|
|
8
8
|
const JSDOM = require('jsdom');
|
|
9
9
|
const SiteMetadataDefaults = require('./vite-react-ssg.4ca822c0.cjs');
|
|
10
|
+
const express = require('express');
|
|
11
|
+
const node_fs = require('node:fs');
|
|
10
12
|
const React = require('react');
|
|
11
13
|
const reactHelmetAsync = require('react-helmet-async');
|
|
12
14
|
const server_js = require('react-router-dom/server.js');
|
|
@@ -16,6 +18,7 @@ const server = require('react-dom/server');
|
|
|
16
18
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
17
19
|
|
|
18
20
|
const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
21
|
+
const express__default = /*#__PURE__*/_interopDefaultCompat(express);
|
|
19
22
|
const React__default = /*#__PURE__*/_interopDefaultCompat(React);
|
|
20
23
|
|
|
21
24
|
function getDefaultExportFromCjs (x) {
|
|
@@ -900,6 +903,39 @@ function routesToPaths(routes) {
|
|
|
900
903
|
getPaths(routes);
|
|
901
904
|
return { paths: Array.from(paths), pathToEntry };
|
|
902
905
|
}
|
|
906
|
+
function createFetchRequest(req) {
|
|
907
|
+
const origin = `${req.protocol}://${req.get("host")}`;
|
|
908
|
+
const url = new URL(req.originalUrl || req.url, origin);
|
|
909
|
+
const controller = new AbortController();
|
|
910
|
+
req.on("close", () => controller.abort());
|
|
911
|
+
const headers = new Headers();
|
|
912
|
+
for (const [key, values] of Object.entries(req.headers)) {
|
|
913
|
+
if (values) {
|
|
914
|
+
if (Array.isArray(values)) {
|
|
915
|
+
for (const value of values)
|
|
916
|
+
headers.append(key, value);
|
|
917
|
+
} else {
|
|
918
|
+
headers.set(key, values);
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
const init = {
|
|
923
|
+
method: req.method,
|
|
924
|
+
headers,
|
|
925
|
+
signal: controller.signal
|
|
926
|
+
};
|
|
927
|
+
if (req.method !== "GET" && req.method !== "HEAD")
|
|
928
|
+
init.body = req.body;
|
|
929
|
+
return new Request(url.href, init);
|
|
930
|
+
}
|
|
931
|
+
async function resolveAlias(config, entry) {
|
|
932
|
+
const resolver = config.createResolver();
|
|
933
|
+
const result = await resolver(entry, config.root);
|
|
934
|
+
return result || node_path.join(config.root, entry);
|
|
935
|
+
}
|
|
936
|
+
const { version } = JSON.parse(
|
|
937
|
+
node_fs.readFileSync(new URL("../../package.json", (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (document.currentScript && document.currentScript.src || new URL('shared/vite-react-ssg.823b31c9.cjs', document.baseURI).href)))).toString()
|
|
938
|
+
);
|
|
903
939
|
|
|
904
940
|
async function getCritters(outDir, options = {}) {
|
|
905
941
|
try {
|
|
@@ -1017,7 +1053,7 @@ function renderPreloadLink(document, file) {
|
|
|
1017
1053
|
});
|
|
1018
1054
|
}
|
|
1019
1055
|
}
|
|
1020
|
-
function createLink(document) {
|
|
1056
|
+
function createLink$1(document) {
|
|
1021
1057
|
return document.createElement("link");
|
|
1022
1058
|
}
|
|
1023
1059
|
function setAttrs(el, attrs) {
|
|
@@ -1029,11 +1065,68 @@ function appendLink(document, attrs) {
|
|
|
1029
1065
|
const exits = document.head.querySelector(`link[href='${attrs.file}']`);
|
|
1030
1066
|
if (exits)
|
|
1031
1067
|
return;
|
|
1032
|
-
const link = createLink(document);
|
|
1068
|
+
const link = createLink$1(document);
|
|
1033
1069
|
setAttrs(link, attrs);
|
|
1034
1070
|
document.head.appendChild(link);
|
|
1035
1071
|
}
|
|
1036
1072
|
|
|
1073
|
+
async function renderHTML({
|
|
1074
|
+
rootContainerId,
|
|
1075
|
+
indexHTML,
|
|
1076
|
+
appHTML,
|
|
1077
|
+
metaAttributes,
|
|
1078
|
+
bodyAttributes,
|
|
1079
|
+
htmlAttributes,
|
|
1080
|
+
initialState
|
|
1081
|
+
}) {
|
|
1082
|
+
const stateScript = initialState ? `
|
|
1083
|
+
<script>window.__INITIAL_STATE__=${initialState}<\/script>` : "";
|
|
1084
|
+
const headStartTag = "<head>";
|
|
1085
|
+
const metaTags = metaAttributes.join("");
|
|
1086
|
+
indexHTML = indexHTML.replace(headStartTag, headStartTag + metaTags);
|
|
1087
|
+
const bodyStartTag = "<body";
|
|
1088
|
+
indexHTML = indexHTML.replace(bodyStartTag, `${bodyStartTag} ${bodyAttributes}`);
|
|
1089
|
+
const htmlStartTag = "<html";
|
|
1090
|
+
indexHTML = indexHTML.replace(htmlStartTag, `${htmlStartTag} ${htmlAttributes}`);
|
|
1091
|
+
const container = `<div id="${rootContainerId}"></div>`;
|
|
1092
|
+
if (indexHTML.includes(container)) {
|
|
1093
|
+
return indexHTML.replace(
|
|
1094
|
+
container,
|
|
1095
|
+
`<div id="${rootContainerId}" data-server-rendered="true">${appHTML}</div>${stateScript}`
|
|
1096
|
+
);
|
|
1097
|
+
}
|
|
1098
|
+
const html5Parser = await import('html5parser');
|
|
1099
|
+
const ast = html5Parser.parse(indexHTML);
|
|
1100
|
+
let renderedOutput;
|
|
1101
|
+
html5Parser.walk(ast, {
|
|
1102
|
+
enter: (node) => {
|
|
1103
|
+
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)) {
|
|
1104
|
+
const attributesStringified = [...node.attributes.map(({ name: { value: name }, value }) => `${name}="${value.value}"`)].join(" ");
|
|
1105
|
+
const indexHTMLBefore = indexHTML.slice(0, node.start);
|
|
1106
|
+
const indexHTMLAfter = indexHTML.slice(node.end);
|
|
1107
|
+
renderedOutput = `${indexHTMLBefore}<${node.name} ${attributesStringified} data-server-rendered="true">${appHTML}</${node.name}>${stateScript}${indexHTMLAfter}`;
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
});
|
|
1111
|
+
if (!renderedOutput)
|
|
1112
|
+
throw new Error(`Could not find a tag with id="${rootContainerId}" to replace it with server-side rendered HTML`);
|
|
1113
|
+
return renderedOutput;
|
|
1114
|
+
}
|
|
1115
|
+
async function detectEntry(root) {
|
|
1116
|
+
const scriptSrcReg = /<script(?:.*?)src=["'](.+?)["'](?!<)(?:.*)\>(?:[\n\r\s]*?)(?:<\/script>)/img;
|
|
1117
|
+
const html = await fs__default.readFile(node_path.join(root, "index.html"), "utf-8");
|
|
1118
|
+
const scripts = [...html.matchAll(scriptSrcReg)];
|
|
1119
|
+
const [, entry] = scripts.find((matchResult) => {
|
|
1120
|
+
const [script] = matchResult;
|
|
1121
|
+
const [, scriptType] = script.match(/.*\stype=(?:'|")?([^>'"\s]+)/i) || [];
|
|
1122
|
+
return scriptType === "module";
|
|
1123
|
+
}) || [];
|
|
1124
|
+
return entry || "src/main.ts";
|
|
1125
|
+
}
|
|
1126
|
+
function createLink(href) {
|
|
1127
|
+
return `<link rel="stylesheet" href="${href}">`;
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1037
1130
|
function DefaultIncludedRoutes(paths, _routes) {
|
|
1038
1131
|
return paths.filter((i) => !i.includes(":") && !i.includes("*"));
|
|
1039
1132
|
}
|
|
@@ -1104,7 +1197,7 @@ async function build(ssgOptions = {}, viteConfig = {}) {
|
|
|
1104
1197
|
const prefix = format === "esm" && process.platform === "win32" ? "file://" : "";
|
|
1105
1198
|
const ext = format === "esm" ? ".mjs" : ".cjs";
|
|
1106
1199
|
const serverEntry = node_path.join(prefix, ssgOut, node_path.parse(ssrEntry).name + ext);
|
|
1107
|
-
const _require = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (document.currentScript && document.currentScript.src || new URL('shared/vite-react-ssg.
|
|
1200
|
+
const _require = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (document.currentScript && document.currentScript.src || new URL('shared/vite-react-ssg.823b31c9.cjs', document.baseURI).href)));
|
|
1108
1201
|
const { createRoot, includedRoutes: serverEntryIncludedRoutes } = format === "esm" ? await import(serverEntry) : _require(serverEntry);
|
|
1109
1202
|
const includedRoutes = serverEntryIncludedRoutes || configIncludedRoutes;
|
|
1110
1203
|
const { routes } = await createRoot(false);
|
|
@@ -1125,7 +1218,7 @@ async function build(ssgOptions = {}, viteConfig = {}) {
|
|
|
1125
1218
|
try {
|
|
1126
1219
|
const appCtx = await createRoot(false, route);
|
|
1127
1220
|
const { routes: routes2, initialState, triggerOnSSRAppRendered, transformState = SiteMetadataDefaults.serializeState } = appCtx;
|
|
1128
|
-
const transformedIndexHTML = await onBeforePageRender?.(route, indexHTML, appCtx);
|
|
1221
|
+
const transformedIndexHTML = await onBeforePageRender?.(route, indexHTML, appCtx) || indexHTML;
|
|
1129
1222
|
const url = new URL(route, "http://vite-react-ssg.com");
|
|
1130
1223
|
url.search = "";
|
|
1131
1224
|
url.hash = "";
|
|
@@ -1136,7 +1229,7 @@ async function build(ssgOptions = {}, viteConfig = {}) {
|
|
|
1136
1229
|
const renderedHTML = await renderHTML({
|
|
1137
1230
|
rootContainerId,
|
|
1138
1231
|
appHTML,
|
|
1139
|
-
indexHTML,
|
|
1232
|
+
indexHTML: transformedIndexHTML,
|
|
1140
1233
|
metaAttributes,
|
|
1141
1234
|
bodyAttributes,
|
|
1142
1235
|
htmlAttributes,
|
|
@@ -1180,69 +1273,11 @@ ${kolorist.gray("[vite-react-ssg]")} ${kolorist.green("Build finished.")}`);
|
|
|
1180
1273
|
}, waitInSeconds * 1e3);
|
|
1181
1274
|
timeout.unref();
|
|
1182
1275
|
}
|
|
1183
|
-
async function detectEntry(root) {
|
|
1184
|
-
const scriptSrcReg = /<script(?:.*?)src=["'](.+?)["'](?!<)(?:.*)\>(?:[\n\r\s]*?)(?:<\/script>)/img;
|
|
1185
|
-
const html = await fs__default.readFile(node_path.join(root, "index.html"), "utf-8");
|
|
1186
|
-
const scripts = [...html.matchAll(scriptSrcReg)];
|
|
1187
|
-
const [, entry] = scripts.find((matchResult) => {
|
|
1188
|
-
const [script] = matchResult;
|
|
1189
|
-
const [, scriptType] = script.match(/.*\stype=(?:'|")?([^>'"\s]+)/i) || [];
|
|
1190
|
-
return scriptType === "module";
|
|
1191
|
-
}) || [];
|
|
1192
|
-
return entry || "src/main.ts";
|
|
1193
|
-
}
|
|
1194
|
-
async function resolveAlias(config, entry) {
|
|
1195
|
-
const resolver = config.createResolver();
|
|
1196
|
-
const result = await resolver(entry, config.root);
|
|
1197
|
-
return result || node_path.join(config.root, entry);
|
|
1198
|
-
}
|
|
1199
1276
|
function rewriteScripts(indexHTML, mode) {
|
|
1200
1277
|
if (!mode || mode === "sync")
|
|
1201
1278
|
return indexHTML;
|
|
1202
1279
|
return indexHTML.replace(/<script type="module" /g, `<script type="module" ${mode} `);
|
|
1203
1280
|
}
|
|
1204
|
-
async function renderHTML({
|
|
1205
|
-
rootContainerId,
|
|
1206
|
-
indexHTML,
|
|
1207
|
-
appHTML,
|
|
1208
|
-
metaAttributes,
|
|
1209
|
-
bodyAttributes,
|
|
1210
|
-
htmlAttributes,
|
|
1211
|
-
initialState
|
|
1212
|
-
}) {
|
|
1213
|
-
const stateScript = initialState ? `
|
|
1214
|
-
<script>window.__INITIAL_STATE__=${initialState}<\/script>` : "";
|
|
1215
|
-
const headStartTag = "<head>";
|
|
1216
|
-
const metaTags = metaAttributes.join("");
|
|
1217
|
-
indexHTML = indexHTML.replace(headStartTag, headStartTag + metaTags);
|
|
1218
|
-
const bodyStartTag = "<body";
|
|
1219
|
-
indexHTML = indexHTML.replace(bodyStartTag, `${bodyStartTag} ${bodyAttributes}`);
|
|
1220
|
-
const htmlStartTag = "<html";
|
|
1221
|
-
indexHTML = indexHTML.replace(htmlStartTag, `${htmlStartTag} ${htmlAttributes}`);
|
|
1222
|
-
const container = `<div id="${rootContainerId}"></div>`;
|
|
1223
|
-
if (indexHTML.includes(container)) {
|
|
1224
|
-
return indexHTML.replace(
|
|
1225
|
-
container,
|
|
1226
|
-
`<div id="${rootContainerId}" data-server-rendered="true">${appHTML}</div>${stateScript}`
|
|
1227
|
-
);
|
|
1228
|
-
}
|
|
1229
|
-
const html5Parser = await import('html5parser');
|
|
1230
|
-
const ast = html5Parser.parse(indexHTML);
|
|
1231
|
-
let renderedOutput;
|
|
1232
|
-
html5Parser.walk(ast, {
|
|
1233
|
-
enter: (node) => {
|
|
1234
|
-
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)) {
|
|
1235
|
-
const attributesStringified = [...node.attributes.map(({ name: { value: name }, value }) => `${name}="${value.value}"`)].join(" ");
|
|
1236
|
-
const indexHTMLBefore = indexHTML.slice(0, node.start);
|
|
1237
|
-
const indexHTMLAfter = indexHTML.slice(node.end);
|
|
1238
|
-
renderedOutput = `${indexHTMLBefore}<${node.name} ${attributesStringified} data-server-rendered="true">${appHTML}</${node.name}>${stateScript}${indexHTMLAfter}`;
|
|
1239
|
-
}
|
|
1240
|
-
}
|
|
1241
|
-
});
|
|
1242
|
-
if (!renderedOutput)
|
|
1243
|
-
throw new Error(`Could not find a tag with id="${rootContainerId}" to replace it with server-side rendered HTML`);
|
|
1244
|
-
return renderedOutput;
|
|
1245
|
-
}
|
|
1246
1281
|
async function formatHtml(html, formatting) {
|
|
1247
1282
|
if (formatting === "minify") {
|
|
1248
1283
|
const htmlMinifier = await import('html-minifier');
|
|
@@ -1278,4 +1313,185 @@ function collectModules(manifest, entry, mods = /* @__PURE__ */ new Set()) {
|
|
|
1278
1313
|
return mods;
|
|
1279
1314
|
}
|
|
1280
1315
|
|
|
1316
|
+
const SHORTCUTS = [
|
|
1317
|
+
{
|
|
1318
|
+
key: "u",
|
|
1319
|
+
description: "show server url",
|
|
1320
|
+
action(vite, _) {
|
|
1321
|
+
vite.config.logger.info("");
|
|
1322
|
+
printServerInfo(vite, true);
|
|
1323
|
+
}
|
|
1324
|
+
},
|
|
1325
|
+
{
|
|
1326
|
+
key: "c",
|
|
1327
|
+
description: "clear console",
|
|
1328
|
+
action(vite, _) {
|
|
1329
|
+
vite.config.logger.clearScreen("error");
|
|
1330
|
+
}
|
|
1331
|
+
},
|
|
1332
|
+
{
|
|
1333
|
+
key: "q",
|
|
1334
|
+
description: "quit",
|
|
1335
|
+
action(_, server) {
|
|
1336
|
+
server.close(() => process.exit());
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
];
|
|
1340
|
+
function bindShortcuts(viteServer, server) {
|
|
1341
|
+
if (!process.stdin.isTTY || process.env.CI)
|
|
1342
|
+
return;
|
|
1343
|
+
viteServer.config.logger.info(
|
|
1344
|
+
kolorist.dim(kolorist.green(" \u279C")) + kolorist.dim(" press ") + kolorist.bold("h") + kolorist.dim(" to show help")
|
|
1345
|
+
);
|
|
1346
|
+
const shortcuts = SHORTCUTS;
|
|
1347
|
+
let actionRunning = false;
|
|
1348
|
+
const onInput = async (input) => {
|
|
1349
|
+
if (input === "" || input === "") {
|
|
1350
|
+
try {
|
|
1351
|
+
await server.close();
|
|
1352
|
+
} finally {
|
|
1353
|
+
process.exit(1);
|
|
1354
|
+
}
|
|
1355
|
+
return;
|
|
1356
|
+
}
|
|
1357
|
+
if (actionRunning)
|
|
1358
|
+
return;
|
|
1359
|
+
if (input === "h") {
|
|
1360
|
+
viteServer.config.logger.info(
|
|
1361
|
+
[
|
|
1362
|
+
"",
|
|
1363
|
+
kolorist.bold(" Shortcuts"),
|
|
1364
|
+
...shortcuts.map(
|
|
1365
|
+
(shortcut2) => kolorist.dim(" press ") + kolorist.bold(shortcut2.key) + kolorist.dim(` to ${shortcut2.description}`)
|
|
1366
|
+
)
|
|
1367
|
+
].join("\n")
|
|
1368
|
+
);
|
|
1369
|
+
}
|
|
1370
|
+
const shortcut = shortcuts.find((shortcut2) => shortcut2.key === input);
|
|
1371
|
+
if (!shortcut)
|
|
1372
|
+
return;
|
|
1373
|
+
actionRunning = true;
|
|
1374
|
+
await shortcut.action(viteServer, server);
|
|
1375
|
+
actionRunning = false;
|
|
1376
|
+
};
|
|
1377
|
+
process.stdin.setRawMode(true);
|
|
1378
|
+
process.stdin.on("data", onInput).setEncoding("utf8").resume();
|
|
1379
|
+
server.on("close", () => {
|
|
1380
|
+
process.stdin.off("data", onInput).pause();
|
|
1381
|
+
});
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
async function dev(ssgOptions = {}, viteConfig = {}) {
|
|
1385
|
+
const mode = process.env.MODE || process.env.NODE_ENV || ssgOptions.mode || "development";
|
|
1386
|
+
const config = await vite.resolveConfig(viteConfig, "serve", mode, mode);
|
|
1387
|
+
const cwd = process.cwd();
|
|
1388
|
+
const root = config.root || cwd;
|
|
1389
|
+
const {
|
|
1390
|
+
entry = await detectEntry(root),
|
|
1391
|
+
onBeforePageRender,
|
|
1392
|
+
onPageRendered,
|
|
1393
|
+
rootContainerId = "root"
|
|
1394
|
+
} = Object.assign({}, config.ssgOptions || {}, ssgOptions);
|
|
1395
|
+
const ssrEntry = await resolveAlias(config, entry);
|
|
1396
|
+
const template = await fs__default.readFile(node_path.join(root, "index.html"), "utf-8");
|
|
1397
|
+
let viteServer;
|
|
1398
|
+
globalThis.__ssr_start_time = performance.now();
|
|
1399
|
+
createServer().then((app) => {
|
|
1400
|
+
const port = viteServer.config.server.port || 5173;
|
|
1401
|
+
const server = app.listen(port, () => {
|
|
1402
|
+
printServerInfo(viteServer);
|
|
1403
|
+
bindShortcuts(viteServer, server);
|
|
1404
|
+
});
|
|
1405
|
+
});
|
|
1406
|
+
async function createServer() {
|
|
1407
|
+
process.env.__DEV_MODE_SSR = "true";
|
|
1408
|
+
const app = express__default();
|
|
1409
|
+
viteServer = await vite.createServer({
|
|
1410
|
+
// ...options,
|
|
1411
|
+
server: { middlewareMode: true },
|
|
1412
|
+
appType: "custom"
|
|
1413
|
+
});
|
|
1414
|
+
app.use(viteServer.middlewares);
|
|
1415
|
+
app.use("*", async (req, res) => {
|
|
1416
|
+
try {
|
|
1417
|
+
const url = req.originalUrl;
|
|
1418
|
+
const indexHTML = await viteServer.transformIndexHtml(url, template);
|
|
1419
|
+
const createRoot = await viteServer.ssrLoadModule(ssrEntry).then((m) => m.createRoot);
|
|
1420
|
+
const appCtx = await createRoot(false, url);
|
|
1421
|
+
const { routes } = appCtx;
|
|
1422
|
+
const transformedIndexHTML = await onBeforePageRender?.(url, indexHTML, appCtx) || indexHTML;
|
|
1423
|
+
const { appHTML, bodyAttributes, htmlAttributes, metaAttributes } = await render([...routes], createFetchRequest(req));
|
|
1424
|
+
const mod = await viteServer.moduleGraph.getModuleByUrl(entry);
|
|
1425
|
+
const assetsUrls = /* @__PURE__ */ new Set();
|
|
1426
|
+
const collectAssets = async (mod2) => {
|
|
1427
|
+
if (!mod2?.ssrTransformResult)
|
|
1428
|
+
return;
|
|
1429
|
+
const { deps = [], dynamicDeps = [] } = mod2?.ssrTransformResult;
|
|
1430
|
+
const allDeps = [...deps, ...dynamicDeps];
|
|
1431
|
+
for (const dep of allDeps) {
|
|
1432
|
+
if (dep.endsWith(".css")) {
|
|
1433
|
+
assetsUrls.add(dep);
|
|
1434
|
+
} else if (dep.endsWith(".ts") || dep.endsWith(".tsx")) {
|
|
1435
|
+
const depModule = await viteServer.moduleGraph.getModuleByUrl(dep);
|
|
1436
|
+
depModule && await collectAssets(depModule);
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
};
|
|
1440
|
+
await collectAssets(mod);
|
|
1441
|
+
const preloadLink = [...assetsUrls].map((item) => createLink(item));
|
|
1442
|
+
metaAttributes.push(...preloadLink);
|
|
1443
|
+
const renderedHTML = await renderHTML({
|
|
1444
|
+
rootContainerId,
|
|
1445
|
+
appHTML,
|
|
1446
|
+
indexHTML: transformedIndexHTML,
|
|
1447
|
+
metaAttributes,
|
|
1448
|
+
bodyAttributes,
|
|
1449
|
+
htmlAttributes,
|
|
1450
|
+
initialState: null
|
|
1451
|
+
});
|
|
1452
|
+
const transformed = await onPageRendered?.(url, renderedHTML, appCtx) || renderedHTML;
|
|
1453
|
+
res.status(200).set({ "Content-Type": "text/html" }).end(transformed);
|
|
1454
|
+
} catch (e) {
|
|
1455
|
+
viteServer.ssrFixStacktrace(e);
|
|
1456
|
+
console.error(`[vite-react-ssg] error: ${e.stack}`);
|
|
1457
|
+
res.status(500).end(e.stack);
|
|
1458
|
+
}
|
|
1459
|
+
});
|
|
1460
|
+
return app;
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
async function printServerInfo(server, onlyUrl = false) {
|
|
1464
|
+
const info = server.config.logger.info;
|
|
1465
|
+
const port = server.config.server.port || 5173;
|
|
1466
|
+
const url = `http://localhost:${port}/`;
|
|
1467
|
+
if (!onlyUrl) {
|
|
1468
|
+
let ssrReadyMessage = " -- SSR";
|
|
1469
|
+
if (globalThis.__ssr_start_time) {
|
|
1470
|
+
ssrReadyMessage += ` ready in ${kolorist.reset(kolorist.bold(`${Math.round(
|
|
1471
|
+
// @ts-expect-error global var
|
|
1472
|
+
performance.now() - globalThis.__ssr_start_time
|
|
1473
|
+
)}ms`))}`;
|
|
1474
|
+
}
|
|
1475
|
+
info(
|
|
1476
|
+
`
|
|
1477
|
+
${kolorist.bgLightCyan(` VITE-REACT-SSG v${version} `)}`,
|
|
1478
|
+
{ clear: !server.config.logger.hasWarned }
|
|
1479
|
+
);
|
|
1480
|
+
info(
|
|
1481
|
+
`${kolorist.cyan(`
|
|
1482
|
+
VITE v${vite.version}`) + kolorist.dim(ssrReadyMessage)}
|
|
1483
|
+
`
|
|
1484
|
+
);
|
|
1485
|
+
}
|
|
1486
|
+
info(
|
|
1487
|
+
kolorist.green(" dev server running at:")
|
|
1488
|
+
);
|
|
1489
|
+
printUrls(url, info);
|
|
1490
|
+
}
|
|
1491
|
+
function printUrls(url, info) {
|
|
1492
|
+
const colorUrl = (url2) => kolorist.cyan(url2.replace(/:(\d+)\//, (_, port) => `:${kolorist.bold(port)}/`));
|
|
1493
|
+
info(` ${kolorist.green("\u279C")} ${kolorist.bold("Local")}: ${colorUrl(url)}`);
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1281
1496
|
exports.build = build;
|
|
1497
|
+
exports.dev = dev;
|
|
@@ -126,6 +126,14 @@ interface ViteReactSSGClientOptions {
|
|
|
126
126
|
* @default `#root`
|
|
127
127
|
*/
|
|
128
128
|
rootContainer?: string | Element;
|
|
129
|
+
/**
|
|
130
|
+
* Use SSR during development.
|
|
131
|
+
*
|
|
132
|
+
* If false, the 'dev' script in 'package.json' needs to be set to `"vite"`.
|
|
133
|
+
*
|
|
134
|
+
* @default true
|
|
135
|
+
*/
|
|
136
|
+
ssrWhenDev?: boolean;
|
|
129
137
|
}
|
|
130
138
|
interface CommonRouteOptions {
|
|
131
139
|
/**
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-react-ssg",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0
|
|
4
|
+
"version": "0.1.0",
|
|
5
5
|
"packageManager": "pnpm@8.6.6",
|
|
6
6
|
"description": "",
|
|
7
7
|
"author": "Riri <Daydreamerriri@outlook.com>",
|
|
@@ -75,6 +75,7 @@
|
|
|
75
75
|
}
|
|
76
76
|
},
|
|
77
77
|
"dependencies": {
|
|
78
|
+
"express": "^4.18.2",
|
|
78
79
|
"fs-extra": "^11.1.1",
|
|
79
80
|
"html-minifier": "^4.0.0",
|
|
80
81
|
"html5parser": "^2.0.2",
|
|
@@ -86,6 +87,7 @@
|
|
|
86
87
|
},
|
|
87
88
|
"devDependencies": {
|
|
88
89
|
"@ririd/eslint-config": "0.6.0",
|
|
90
|
+
"@types/express": "^4.17.17",
|
|
89
91
|
"@types/fs-extra": "^11.0.1",
|
|
90
92
|
"@types/html-minifier": "^4.0.2",
|
|
91
93
|
"@types/jsdom": "^21.1.1",
|
|
@@ -110,4 +112,4 @@
|
|
|
110
112
|
"vite-plugin-pwa": "^0.16.4",
|
|
111
113
|
"vitest": "0.33.0"
|
|
112
114
|
}
|
|
113
|
-
}
|
|
115
|
+
}
|