vite-react-ssg 0.6.1 → 0.6.2
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 +2 -4
- package/dist/client/single-page.d.cts +2 -2
- package/dist/client/single-page.d.mts +2 -2
- package/dist/client/single-page.d.ts +2 -2
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/node/cli.cjs +9 -38
- package/dist/node/cli.mjs +8 -37
- package/dist/node.cjs +197 -310
- package/dist/node.d.cts +2 -2
- package/dist/node.d.mts +2 -2
- package/dist/node.d.ts +2 -2
- package/dist/node.mjs +198 -309
- package/dist/shared/{vite-react-ssg.d734eb79.d.cts → vite-react-ssg.870c683b.d.cts} +3 -3
- package/dist/shared/{vite-react-ssg.d734eb79.d.mts → vite-react-ssg.870c683b.d.mts} +3 -3
- package/dist/shared/{vite-react-ssg.d734eb79.d.ts → vite-react-ssg.870c683b.d.ts} +3 -3
- package/package.json +7 -5
package/dist/node.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { InlineConfig } from 'vite';
|
|
2
|
-
import { b as ViteReactSSGOptions } from './shared/vite-react-ssg.
|
|
2
|
+
import { b as ViteReactSSGOptions } from './shared/vite-react-ssg.870c683b.js';
|
|
3
3
|
import 'critters';
|
|
4
4
|
import 'react';
|
|
5
5
|
import 'react-router-dom';
|
|
6
6
|
|
|
7
7
|
declare function build(ssgOptions?: Partial<ViteReactSSGOptions>, viteConfig?: InlineConfig): Promise<void>;
|
|
8
8
|
|
|
9
|
-
declare function dev(ssgOptions?: Partial<ViteReactSSGOptions>, viteConfig?: InlineConfig): Promise<void>;
|
|
9
|
+
declare function dev(ssgOptions?: Partial<ViteReactSSGOptions>, viteConfig?: InlineConfig, customOptions?: unknown): Promise<void>;
|
|
10
10
|
|
|
11
11
|
export { build, dev };
|
package/dist/node.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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,
|
|
3
|
+
import { gray, yellow, blue, dim, cyan, red, green, reset, bold, bgLightCyan } from 'kolorist';
|
|
4
4
|
import fs from 'fs-extra';
|
|
5
5
|
import { resolveConfig, build as build$1, mergeConfig, version as version$1, createServer } from 'vite';
|
|
6
6
|
import { JSDOM } from 'jsdom';
|
|
@@ -10,9 +10,6 @@ import React from 'react';
|
|
|
10
10
|
import { HelmetProvider } from 'react-helmet-async';
|
|
11
11
|
import { Writable } from 'node:stream';
|
|
12
12
|
import { renderToPipeableStream } from 'react-dom/server';
|
|
13
|
-
import https from 'node:https';
|
|
14
|
-
import express from 'express';
|
|
15
|
-
import { certificateFor } from '@childrentime/devcert';
|
|
16
13
|
|
|
17
14
|
function getDefaultExportFromCjs (x) {
|
|
18
15
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
@@ -857,10 +854,18 @@ async function routesToPaths(routes) {
|
|
|
857
854
|
if (!routes || routes.length === 0)
|
|
858
855
|
return { paths: ["/"], pathToEntry };
|
|
859
856
|
const paths = /* @__PURE__ */ new Set();
|
|
860
|
-
const lazyPaths = /* @__PURE__ */ new Set();
|
|
861
857
|
const getPaths = async (routes2, prefix = "") => {
|
|
862
858
|
prefix = prefix.replace(/\/$/g, "");
|
|
863
|
-
for (
|
|
859
|
+
for (let route of routes2) {
|
|
860
|
+
if (route.lazy) {
|
|
861
|
+
const lazyData = await route.lazy();
|
|
862
|
+
if (lazyData) {
|
|
863
|
+
route = {
|
|
864
|
+
...route,
|
|
865
|
+
...lazyData
|
|
866
|
+
};
|
|
867
|
+
}
|
|
868
|
+
}
|
|
864
869
|
let path = route.path;
|
|
865
870
|
path = handlePath(path, prefix, route.entry);
|
|
866
871
|
if (route.getStaticPaths && isDynamicSegmentsRoute(path)) {
|
|
@@ -871,8 +876,6 @@ async function routesToPaths(routes) {
|
|
|
871
876
|
await getPaths(route.children, staticPath);
|
|
872
877
|
}
|
|
873
878
|
}
|
|
874
|
-
if (route.lazy)
|
|
875
|
-
lazyPaths.add(route.index ? prefix : path ?? "");
|
|
876
879
|
if (route.index)
|
|
877
880
|
addEntry(prefix, route.entry);
|
|
878
881
|
if (Array.isArray(route.children))
|
|
@@ -880,7 +883,7 @@ async function routesToPaths(routes) {
|
|
|
880
883
|
}
|
|
881
884
|
};
|
|
882
885
|
await getPaths(routes);
|
|
883
|
-
return { paths: Array.from(paths), pathToEntry
|
|
886
|
+
return { paths: Array.from(paths), pathToEntry };
|
|
884
887
|
function handlePath(path, prefix, entry) {
|
|
885
888
|
if (path != null) {
|
|
886
889
|
path = prefix && !path.startsWith("/") ? `${prefix}${path ? `/${path}` : ""}` : path;
|
|
@@ -894,31 +897,6 @@ async function routesToPaths(routes) {
|
|
|
894
897
|
return path;
|
|
895
898
|
}
|
|
896
899
|
}
|
|
897
|
-
function createFetchRequest(req) {
|
|
898
|
-
const origin = `${req.protocol}://${req.get("host")}`;
|
|
899
|
-
const url = new URL(req.originalUrl || req.url, origin);
|
|
900
|
-
const controller = new AbortController();
|
|
901
|
-
req.on("close", () => controller.abort());
|
|
902
|
-
const headers = new Headers();
|
|
903
|
-
for (const [key, values] of Object.entries(req.headers)) {
|
|
904
|
-
if (values) {
|
|
905
|
-
if (Array.isArray(values)) {
|
|
906
|
-
for (const value of values)
|
|
907
|
-
headers.append(key, value);
|
|
908
|
-
} else {
|
|
909
|
-
headers.set(key, values);
|
|
910
|
-
}
|
|
911
|
-
}
|
|
912
|
-
}
|
|
913
|
-
const init = {
|
|
914
|
-
method: req.method,
|
|
915
|
-
headers,
|
|
916
|
-
signal: controller.signal
|
|
917
|
-
};
|
|
918
|
-
if (req.method !== "GET" && req.method !== "HEAD")
|
|
919
|
-
init.body = req.body;
|
|
920
|
-
return new Request(url.href, init);
|
|
921
|
-
}
|
|
922
900
|
async function resolveAlias(config, entry) {
|
|
923
901
|
const resolver = config.createResolver();
|
|
924
902
|
const result = await resolver(entry, config.root);
|
|
@@ -951,10 +929,6 @@ function withTrailingSlash(path) {
|
|
|
951
929
|
return `${path}/`;
|
|
952
930
|
return path;
|
|
953
931
|
}
|
|
954
|
-
const postfixRE = /[?#].*$/s;
|
|
955
|
-
function cleanUrl(url) {
|
|
956
|
-
return url.replace(postfixRE, "");
|
|
957
|
-
}
|
|
958
932
|
const dynamicRE = /[:*?]/;
|
|
959
933
|
function isDynamicSegmentsRoute(route) {
|
|
960
934
|
if (!route)
|
|
@@ -1054,17 +1028,6 @@ async function render(routesOrApp, request, styleCollector, basename) {
|
|
|
1054
1028
|
const { htmlAttributes, bodyAttributes, metaAttributes, styleTag } = extractHelmet(helmetContext, styleCollector);
|
|
1055
1029
|
return { appHTML, htmlAttributes, bodyAttributes, metaAttributes, styleTag, routerContext: context };
|
|
1056
1030
|
}
|
|
1057
|
-
async function preLoad(routes, paths) {
|
|
1058
|
-
if (!paths || paths.length === 0)
|
|
1059
|
-
return routes;
|
|
1060
|
-
const { createStaticHandler } = await import('react-router-dom/server.js');
|
|
1061
|
-
const { dataRoutes, query } = createStaticHandler(routes);
|
|
1062
|
-
await Promise.all(paths.map(async (path) => {
|
|
1063
|
-
const request = createRequest(path);
|
|
1064
|
-
return query(request);
|
|
1065
|
-
}));
|
|
1066
|
-
return dataRoutes;
|
|
1067
|
-
}
|
|
1068
1031
|
function extractHelmet(context, styleCollector) {
|
|
1069
1032
|
const { helmet } = context;
|
|
1070
1033
|
const htmlAttributes = helmet.htmlAttributes.toString();
|
|
@@ -1080,56 +1043,6 @@ function extractHelmet(context, styleCollector) {
|
|
|
1080
1043
|
return { htmlAttributes, bodyAttributes, metaAttributes, styleTag };
|
|
1081
1044
|
}
|
|
1082
1045
|
|
|
1083
|
-
function renderPreloadLinks(document, modules, ssrManifest) {
|
|
1084
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1085
|
-
const preloadLinks = [];
|
|
1086
|
-
Array.from(modules).forEach((id) => {
|
|
1087
|
-
const files = ssrManifest[id] || [];
|
|
1088
|
-
files.forEach((file) => {
|
|
1089
|
-
if (!preloadLinks.includes(file))
|
|
1090
|
-
preloadLinks.push(file);
|
|
1091
|
-
});
|
|
1092
|
-
});
|
|
1093
|
-
if (preloadLinks) {
|
|
1094
|
-
preloadLinks.forEach((file) => {
|
|
1095
|
-
if (!seen.has(file)) {
|
|
1096
|
-
seen.add(file);
|
|
1097
|
-
renderPreloadLink(document, file);
|
|
1098
|
-
}
|
|
1099
|
-
});
|
|
1100
|
-
}
|
|
1101
|
-
}
|
|
1102
|
-
function renderPreloadLink(document, file) {
|
|
1103
|
-
if (file.endsWith(".js")) {
|
|
1104
|
-
appendLink(document, {
|
|
1105
|
-
rel: "modulepreload",
|
|
1106
|
-
crossOrigin: "",
|
|
1107
|
-
href: file
|
|
1108
|
-
});
|
|
1109
|
-
} else if (file.endsWith(".css")) {
|
|
1110
|
-
appendLink(document, {
|
|
1111
|
-
rel: "stylesheet",
|
|
1112
|
-
href: file
|
|
1113
|
-
});
|
|
1114
|
-
}
|
|
1115
|
-
}
|
|
1116
|
-
function createLink$1(document) {
|
|
1117
|
-
return document.createElement("link");
|
|
1118
|
-
}
|
|
1119
|
-
function setAttrs(el, attrs) {
|
|
1120
|
-
const keys = Object.keys(attrs);
|
|
1121
|
-
for (const key of keys)
|
|
1122
|
-
el.setAttribute(key, attrs[key]);
|
|
1123
|
-
}
|
|
1124
|
-
function appendLink(document, attrs) {
|
|
1125
|
-
const exits = document.head.querySelector(`link[href='${attrs.file}']`);
|
|
1126
|
-
if (exits)
|
|
1127
|
-
return;
|
|
1128
|
-
const link = createLink$1(document);
|
|
1129
|
-
setAttrs(link, attrs);
|
|
1130
|
-
document.head.appendChild(link);
|
|
1131
|
-
}
|
|
1132
|
-
|
|
1133
1046
|
async function renderHTML({
|
|
1134
1047
|
rootContainerId,
|
|
1135
1048
|
indexHTML,
|
|
@@ -1183,10 +1096,61 @@ async function detectEntry(root) {
|
|
|
1183
1096
|
}) || [];
|
|
1184
1097
|
return entry || "src/main.ts";
|
|
1185
1098
|
}
|
|
1186
|
-
function createLink(href) {
|
|
1099
|
+
function createLink$1(href) {
|
|
1187
1100
|
return `<link rel="stylesheet" href="${href}">`;
|
|
1188
1101
|
}
|
|
1189
1102
|
|
|
1103
|
+
function renderPreloadLinks(document, modules, ssrManifest) {
|
|
1104
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1105
|
+
const preloadLinks = [];
|
|
1106
|
+
Array.from(modules).forEach((id) => {
|
|
1107
|
+
const files = ssrManifest[id] || [];
|
|
1108
|
+
files.forEach((file) => {
|
|
1109
|
+
if (!preloadLinks.includes(file))
|
|
1110
|
+
preloadLinks.push(file);
|
|
1111
|
+
});
|
|
1112
|
+
});
|
|
1113
|
+
if (preloadLinks) {
|
|
1114
|
+
preloadLinks.forEach((file) => {
|
|
1115
|
+
if (!seen.has(file)) {
|
|
1116
|
+
seen.add(file);
|
|
1117
|
+
renderPreloadLink(document, file);
|
|
1118
|
+
}
|
|
1119
|
+
});
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
function renderPreloadLink(document, file) {
|
|
1123
|
+
if (file.endsWith(".js")) {
|
|
1124
|
+
appendLink(document, {
|
|
1125
|
+
rel: "modulepreload",
|
|
1126
|
+
crossOrigin: "",
|
|
1127
|
+
href: file
|
|
1128
|
+
});
|
|
1129
|
+
} else if (file.endsWith(".css")) {
|
|
1130
|
+
appendLink(document, {
|
|
1131
|
+
rel: "stylesheet",
|
|
1132
|
+
href: file,
|
|
1133
|
+
crossOrigin: ""
|
|
1134
|
+
});
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
function createLink(document) {
|
|
1138
|
+
return document.createElement("link");
|
|
1139
|
+
}
|
|
1140
|
+
function setAttrs(el, attrs) {
|
|
1141
|
+
const keys = Object.keys(attrs);
|
|
1142
|
+
for (const key of keys)
|
|
1143
|
+
el.setAttribute(key, attrs[key]);
|
|
1144
|
+
}
|
|
1145
|
+
function appendLink(document, attrs) {
|
|
1146
|
+
const exits = document.head.querySelector(`link[href='${attrs.file}']`);
|
|
1147
|
+
if (exits)
|
|
1148
|
+
return;
|
|
1149
|
+
const link = createLink(document);
|
|
1150
|
+
setAttrs(link, attrs);
|
|
1151
|
+
document.head.appendChild(link);
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1190
1154
|
function DefaultIncludedRoutes(paths, _routes) {
|
|
1191
1155
|
return paths.filter((i) => !i.includes(":") && !i.includes("*"));
|
|
1192
1156
|
}
|
|
@@ -1268,9 +1232,7 @@ async function build(ssgOptions = {}, viteConfig = {}) {
|
|
|
1268
1232
|
const { createRoot, includedRoutes: serverEntryIncludedRoutes } = format === "esm" ? await import(serverEntry) : _require(serverEntry);
|
|
1269
1233
|
const includedRoutes = serverEntryIncludedRoutes || configIncludedRoutes;
|
|
1270
1234
|
const { routes } = await createRoot(false);
|
|
1271
|
-
const {
|
|
1272
|
-
const dataRoutes = await preLoad([...routes || []], lazyPaths);
|
|
1273
|
-
const { paths, pathToEntry } = await routesToPaths(dataRoutes);
|
|
1235
|
+
const { paths, pathToEntry } = await routesToPaths(routes);
|
|
1274
1236
|
let routesPaths = includeAllRoutes ? paths : await includedRoutes(paths, routes || []);
|
|
1275
1237
|
routesPaths = DefaultIncludedRoutes(routesPaths);
|
|
1276
1238
|
routesPaths = Array.from(new Set(routesPaths));
|
|
@@ -1310,8 +1272,10 @@ async function build(ssgOptions = {}, viteConfig = {}) {
|
|
|
1310
1272
|
renderPreloadLinks(jsdom.window.document, modules, ssrManifest);
|
|
1311
1273
|
const html = jsdom.serialize();
|
|
1312
1274
|
let transformed = await onPageRendered?.(path, html, appCtx) || html;
|
|
1313
|
-
if (critters)
|
|
1275
|
+
if (critters) {
|
|
1314
1276
|
transformed = await crittersQueue.add(() => critters.process(transformed));
|
|
1277
|
+
transformed = transformed.replace(/<link\srel="stylesheet"/g, '<link rel="stylesheet" crossorigin');
|
|
1278
|
+
}
|
|
1315
1279
|
if (styleTag)
|
|
1316
1280
|
transformed = transformed.replace("<head>", `<head>${styleTag}`);
|
|
1317
1281
|
const formatted = await formatHtml(transformed, formatting);
|
|
@@ -1361,9 +1325,14 @@ async function formatHtml(html, formatting) {
|
|
|
1361
1325
|
minifyCSS: true
|
|
1362
1326
|
});
|
|
1363
1327
|
} else if (formatting === "prettify") {
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1328
|
+
try {
|
|
1329
|
+
const prettier = (await import('prettier/esm/standalone.mjs')).default;
|
|
1330
|
+
const parserHTML = (await import('prettier/esm/parser-html.mjs')).default;
|
|
1331
|
+
return prettier.format(html, { semi: false, parser: "html", plugins: [parserHTML] });
|
|
1332
|
+
} catch (e) {
|
|
1333
|
+
console.error(`${gray("[vite-react-ssg]")} ${red(`Error formatting html: ${e?.message}`)}`);
|
|
1334
|
+
return html;
|
|
1335
|
+
}
|
|
1367
1336
|
}
|
|
1368
1337
|
return html;
|
|
1369
1338
|
}
|
|
@@ -1385,114 +1354,48 @@ function collectModules(manifest, entry, mods = /* @__PURE__ */ new Set()) {
|
|
|
1385
1354
|
return mods;
|
|
1386
1355
|
}
|
|
1387
1356
|
|
|
1388
|
-
|
|
1389
|
-
{
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
printServerInfo(vite, true);
|
|
1395
|
-
}
|
|
1396
|
-
},
|
|
1397
|
-
{
|
|
1398
|
-
key: "c",
|
|
1399
|
-
description: "clear console",
|
|
1400
|
-
action(vite, _) {
|
|
1401
|
-
vite.config.logger.clearScreen("error");
|
|
1402
|
-
}
|
|
1403
|
-
},
|
|
1404
|
-
{
|
|
1405
|
-
key: "q",
|
|
1406
|
-
description: "quit",
|
|
1407
|
-
action(_, server) {
|
|
1408
|
-
server.close(() => process.exit());
|
|
1409
|
-
}
|
|
1357
|
+
function invariant(value, message) {
|
|
1358
|
+
if (value === false || value === null || typeof value === "undefined") {
|
|
1359
|
+
console.error(
|
|
1360
|
+
"The following error is a bug in Remix; please open an issue! https://github.com/remix-run/remix/issues/new"
|
|
1361
|
+
);
|
|
1362
|
+
throw new Error(message);
|
|
1410
1363
|
}
|
|
1411
|
-
];
|
|
1412
|
-
function bindShortcuts(viteServer, server) {
|
|
1413
|
-
if (!process.stdin.isTTY || process.env.CI)
|
|
1414
|
-
return;
|
|
1415
|
-
viteServer.config.logger.info(
|
|
1416
|
-
dim(green(" \u279C")) + dim(" press ") + bold("h") + dim(" to show help")
|
|
1417
|
-
);
|
|
1418
|
-
const shortcuts = SHORTCUTS;
|
|
1419
|
-
let actionRunning = false;
|
|
1420
|
-
const onInput = async (input) => {
|
|
1421
|
-
if (input === "" || input === "") {
|
|
1422
|
-
try {
|
|
1423
|
-
await server.close();
|
|
1424
|
-
} finally {
|
|
1425
|
-
process.exit(1);
|
|
1426
|
-
}
|
|
1427
|
-
return;
|
|
1428
|
-
}
|
|
1429
|
-
if (actionRunning)
|
|
1430
|
-
return;
|
|
1431
|
-
if (input === "h") {
|
|
1432
|
-
viteServer.config.logger.info(
|
|
1433
|
-
[
|
|
1434
|
-
"",
|
|
1435
|
-
bold(" Shortcuts"),
|
|
1436
|
-
...shortcuts.map(
|
|
1437
|
-
(shortcut2) => dim(" press ") + bold(shortcut2.key) + dim(` to ${shortcut2.description}`)
|
|
1438
|
-
)
|
|
1439
|
-
].join("\n")
|
|
1440
|
-
);
|
|
1441
|
-
}
|
|
1442
|
-
const shortcut = shortcuts.find((shortcut2) => shortcut2.key === input);
|
|
1443
|
-
if (!shortcut)
|
|
1444
|
-
return;
|
|
1445
|
-
actionRunning = true;
|
|
1446
|
-
await shortcut.action(viteServer, server);
|
|
1447
|
-
actionRunning = false;
|
|
1448
|
-
};
|
|
1449
|
-
process.stdin.setRawMode(true);
|
|
1450
|
-
process.stdin.on("data", onInput).setEncoding("utf8").resume();
|
|
1451
|
-
server.on("close", () => {
|
|
1452
|
-
process.stdin.off("data", onInput).pause();
|
|
1453
|
-
});
|
|
1454
1364
|
}
|
|
1455
1365
|
|
|
1456
|
-
function
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
});
|
|
1467
|
-
res.end();
|
|
1468
|
-
return;
|
|
1469
|
-
}
|
|
1470
|
-
const redirectPath = withTrailingSlash(url) !== base ? joinUrlSegments(base, url) : base;
|
|
1471
|
-
if (req.headers.accept?.includes("text/html")) {
|
|
1472
|
-
res.writeHead(404, {
|
|
1473
|
-
"Content-Type": "text/html"
|
|
1474
|
-
});
|
|
1475
|
-
res.end(
|
|
1476
|
-
`The server is configured with a public base URL of ${base} - did you mean to visit <a href="${redirectPath}">${redirectPath}</a> instead?`
|
|
1477
|
-
);
|
|
1478
|
-
} else {
|
|
1479
|
-
res.writeHead(404, {
|
|
1480
|
-
"Content-Type": "text/plain"
|
|
1481
|
-
});
|
|
1482
|
-
res.end(
|
|
1483
|
-
`The server is configured with a public base URL of ${base} - did you mean to visit ${redirectPath} instead?`
|
|
1484
|
-
);
|
|
1366
|
+
function fromNodeHeaders(nodeHeaders) {
|
|
1367
|
+
const headers = new Headers();
|
|
1368
|
+
for (const [key, values] of Object.entries(nodeHeaders)) {
|
|
1369
|
+
if (values) {
|
|
1370
|
+
if (Array.isArray(values)) {
|
|
1371
|
+
for (const value of values)
|
|
1372
|
+
headers.append(key, value);
|
|
1373
|
+
} else {
|
|
1374
|
+
headers.set(key, values);
|
|
1375
|
+
}
|
|
1485
1376
|
}
|
|
1377
|
+
}
|
|
1378
|
+
return headers;
|
|
1379
|
+
}
|
|
1380
|
+
function fromNodeRequest(nodeReq) {
|
|
1381
|
+
const origin = nodeReq.headers.origin && nodeReq.headers.origin !== "null" ? nodeReq.headers.origin : `http://${nodeReq.headers.host}`;
|
|
1382
|
+
invariant(
|
|
1383
|
+
nodeReq.originalUrl,
|
|
1384
|
+
"Expected `nodeReq.originalUrl` to be defined"
|
|
1385
|
+
);
|
|
1386
|
+
const url = new URL(nodeReq.originalUrl, origin);
|
|
1387
|
+
const init = {
|
|
1388
|
+
method: nodeReq.method,
|
|
1389
|
+
headers: fromNodeHeaders(nodeReq.headers)
|
|
1486
1390
|
};
|
|
1391
|
+
return new Request(url.href, init);
|
|
1487
1392
|
}
|
|
1488
1393
|
|
|
1489
|
-
async function dev(ssgOptions = {}, viteConfig = {}) {
|
|
1394
|
+
async function dev(ssgOptions = {}, viteConfig = {}, customOptions) {
|
|
1490
1395
|
const mode = process.env.MODE || process.env.NODE_ENV || ssgOptions.mode || "development";
|
|
1491
1396
|
const config = await resolveConfig(viteConfig, "serve", mode, mode);
|
|
1492
1397
|
const cwd = process.cwd();
|
|
1493
1398
|
const root = config.root || cwd;
|
|
1494
|
-
const httpsOptions = config.server.https;
|
|
1495
|
-
setBase(config.rawBase);
|
|
1496
1399
|
const {
|
|
1497
1400
|
entry = await detectEntry(root),
|
|
1498
1401
|
onBeforePageRender,
|
|
@@ -1504,21 +1407,12 @@ async function dev(ssgOptions = {}, viteConfig = {}) {
|
|
|
1504
1407
|
const template = await fs.readFile(join(root, "index.html"), "utf-8");
|
|
1505
1408
|
let viteServer;
|
|
1506
1409
|
globalThis.__ssr_start_time = performance.now();
|
|
1507
|
-
createServer$1().
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
printServerInfo(viteServer, false, true);
|
|
1514
|
-
bindShortcuts(viteServer, server);
|
|
1515
|
-
});
|
|
1516
|
-
} else {
|
|
1517
|
-
const server = app.listen(port, () => {
|
|
1518
|
-
printServerInfo(viteServer);
|
|
1519
|
-
bindShortcuts(viteServer, server);
|
|
1520
|
-
});
|
|
1521
|
-
}
|
|
1410
|
+
createServer$1().catch((err) => {
|
|
1411
|
+
console.error(
|
|
1412
|
+
`${red(`failed to start server. error:`)}
|
|
1413
|
+
${err.stack}`
|
|
1414
|
+
);
|
|
1415
|
+
process.exit(1);
|
|
1522
1416
|
});
|
|
1523
1417
|
async function createServer$1() {
|
|
1524
1418
|
process.env.__DEV_MODE_SSR = "true";
|
|
@@ -1526,108 +1420,103 @@ async function dev(ssgOptions = {}, viteConfig = {}) {
|
|
|
1526
1420
|
const { jsdomGlobal } = await import('./chunks/jsdomGlobal.mjs');
|
|
1527
1421
|
jsdomGlobal();
|
|
1528
1422
|
}
|
|
1529
|
-
const app = express();
|
|
1530
1423
|
viteServer = await createServer({
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1424
|
+
...viteConfig,
|
|
1425
|
+
plugins: [
|
|
1426
|
+
...viteConfig.plugins ?? [],
|
|
1427
|
+
{
|
|
1428
|
+
name: "vite-react-ssg:dev-server-remix",
|
|
1429
|
+
configureServer(server) {
|
|
1430
|
+
return () => {
|
|
1431
|
+
server.middlewares.use(async (req, res, _next) => {
|
|
1432
|
+
try {
|
|
1433
|
+
const url = req.originalUrl;
|
|
1434
|
+
const indexHTML = await viteServer.transformIndexHtml(url, template);
|
|
1435
|
+
const createRoot = await viteServer.ssrLoadModule(ssrEntry).then((m) => m.createRoot);
|
|
1436
|
+
const appCtx = await createRoot(false, url);
|
|
1437
|
+
const { routes, getStyleCollector, base, app } = appCtx;
|
|
1438
|
+
const transformedIndexHTML = await onBeforePageRender?.(url, indexHTML, appCtx) || indexHTML;
|
|
1439
|
+
const styleCollector = getStyleCollector ? await getStyleCollector() : null;
|
|
1440
|
+
const { appHTML, bodyAttributes, htmlAttributes, metaAttributes, styleTag, routerContext } = await render(app ?? [...routes], fromNodeRequest(req), styleCollector, base);
|
|
1441
|
+
metaAttributes.push(styleTag);
|
|
1442
|
+
const matchesEntries = routerContext?.matches.map((match) => match.route.entry).filter((entry2) => !!entry2).map((entry2) => entry2[0] === "/" ? entry2 : `/${entry2}`) ?? [];
|
|
1443
|
+
const mods = await Promise.all(
|
|
1444
|
+
[ssrEntry, entry, ...matchesEntries].map(async (entry2) => await viteServer.moduleGraph.getModuleByUrl(entry2))
|
|
1445
|
+
);
|
|
1446
|
+
const assetsUrls = /* @__PURE__ */ new Set();
|
|
1447
|
+
const collectAssets = async (mod) => {
|
|
1448
|
+
if (!mod || !mod?.ssrTransformResult)
|
|
1449
|
+
return;
|
|
1450
|
+
const { deps = [], dynamicDeps = [] } = mod?.ssrTransformResult;
|
|
1451
|
+
const allDeps = [...deps, ...dynamicDeps];
|
|
1452
|
+
for (const dep of allDeps) {
|
|
1453
|
+
if (dep.endsWith(".css")) {
|
|
1454
|
+
assetsUrls.add(dep);
|
|
1455
|
+
} else if (dep.endsWith(".ts") || dep.endsWith(".tsx")) {
|
|
1456
|
+
const depModule = await viteServer.moduleGraph.getModuleByUrl(dep);
|
|
1457
|
+
depModule && await collectAssets(depModule);
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
};
|
|
1461
|
+
await Promise.all(mods.map(async (mod) => collectAssets(mod)));
|
|
1462
|
+
const preloadLink = [...assetsUrls].map((item) => createLink$1(joinUrlSegments(config.base, item)));
|
|
1463
|
+
metaAttributes.push(...preloadLink);
|
|
1464
|
+
const renderedHTML = await renderHTML({
|
|
1465
|
+
rootContainerId,
|
|
1466
|
+
appHTML,
|
|
1467
|
+
indexHTML: transformedIndexHTML,
|
|
1468
|
+
metaAttributes,
|
|
1469
|
+
bodyAttributes,
|
|
1470
|
+
htmlAttributes,
|
|
1471
|
+
initialState: null
|
|
1472
|
+
});
|
|
1473
|
+
const transformed = await onPageRendered?.(url, renderedHTML, appCtx) || renderedHTML;
|
|
1474
|
+
res.statusCode = 200;
|
|
1475
|
+
res.setHeader("Content-Type", "text/html");
|
|
1476
|
+
res.end(transformed);
|
|
1477
|
+
} catch (e) {
|
|
1478
|
+
viteServer.ssrFixStacktrace(e);
|
|
1479
|
+
console.error(`[vite-react-ssg] error: ${e.stack}`);
|
|
1480
|
+
res.statusCode = 500;
|
|
1481
|
+
res.end(e.stack);
|
|
1482
|
+
}
|
|
1483
|
+
});
|
|
1484
|
+
};
|
|
1567
1485
|
}
|
|
1568
|
-
}
|
|
1569
|
-
|
|
1570
|
-
const preloadLink = [...assetsUrls].map((item) => createLink(item));
|
|
1571
|
-
metaAttributes.push(...preloadLink);
|
|
1572
|
-
const renderedHTML = await renderHTML({
|
|
1573
|
-
rootContainerId,
|
|
1574
|
-
appHTML,
|
|
1575
|
-
indexHTML: transformedIndexHTML,
|
|
1576
|
-
metaAttributes,
|
|
1577
|
-
bodyAttributes,
|
|
1578
|
-
htmlAttributes,
|
|
1579
|
-
initialState: null
|
|
1580
|
-
});
|
|
1581
|
-
const transformed = await onPageRendered?.(url, renderedHTML, appCtx) || renderedHTML;
|
|
1582
|
-
res.status(200).set({ "Content-Type": "text/html" }).end(transformed);
|
|
1583
|
-
} catch (e) {
|
|
1584
|
-
viteServer.ssrFixStacktrace(e);
|
|
1585
|
-
console.error(`[vite-react-ssg] error: ${e.stack}`);
|
|
1586
|
-
res.status(500).end(e.stack);
|
|
1587
|
-
}
|
|
1486
|
+
}
|
|
1487
|
+
]
|
|
1588
1488
|
});
|
|
1589
|
-
|
|
1489
|
+
await viteServer.listen();
|
|
1490
|
+
printServerInfo(viteServer, !!customOptions);
|
|
1491
|
+
viteServer.bindCLIShortcuts({ print: true });
|
|
1492
|
+
return viteServer;
|
|
1590
1493
|
}
|
|
1591
1494
|
}
|
|
1592
|
-
async function printServerInfo(server, onlyUrl = false
|
|
1495
|
+
async function printServerInfo(server, onlyUrl = false) {
|
|
1496
|
+
if (onlyUrl)
|
|
1497
|
+
return server.printUrls();
|
|
1593
1498
|
const info = server.config.logger.info;
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
)}ms`))}`;
|
|
1604
|
-
}
|
|
1605
|
-
info(
|
|
1606
|
-
`
|
|
1499
|
+
let ssrReadyMessage = " -- SSR";
|
|
1500
|
+
if (globalThis.__ssr_start_time) {
|
|
1501
|
+
ssrReadyMessage += ` ready in ${reset(bold(`${Math.round(
|
|
1502
|
+
// @ts-expect-error global var
|
|
1503
|
+
performance.now() - globalThis.__ssr_start_time
|
|
1504
|
+
)}ms`))}`;
|
|
1505
|
+
}
|
|
1506
|
+
info(
|
|
1507
|
+
`
|
|
1607
1508
|
${bgLightCyan(` VITE-REACT-SSG v${version} `)}`,
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1509
|
+
{ clear: !server.config.logger.hasWarned }
|
|
1510
|
+
);
|
|
1511
|
+
info(
|
|
1512
|
+
`${cyan(`
|
|
1612
1513
|
VITE v${version$1}`) + dim(ssrReadyMessage)}
|
|
1613
1514
|
`
|
|
1614
|
-
|
|
1615
|
-
}
|
|
1515
|
+
);
|
|
1616
1516
|
info(
|
|
1617
1517
|
green(" dev server running at:")
|
|
1618
1518
|
);
|
|
1619
|
-
printUrls(
|
|
1620
|
-
}
|
|
1621
|
-
function printUrls(url, info) {
|
|
1622
|
-
const colorUrl = (url2) => cyan(url2.replace(/:(\d+)\//, (_, port) => `:${bold(port)}/`));
|
|
1623
|
-
info(` ${green("\u279C")} ${bold("Local")}: ${colorUrl(url)}`);
|
|
1624
|
-
}
|
|
1625
|
-
let base = "";
|
|
1626
|
-
function getBase() {
|
|
1627
|
-
return base;
|
|
1628
|
-
}
|
|
1629
|
-
function setBase(newBase) {
|
|
1630
|
-
base = newBase;
|
|
1519
|
+
server.printUrls();
|
|
1631
1520
|
}
|
|
1632
1521
|
|
|
1633
1522
|
export { build, dev };
|
|
@@ -110,9 +110,9 @@ interface ViteReactSSGContext<HasRouter extends boolean = true> {
|
|
|
110
110
|
routerOptions: HasRouter extends true ? RouterOptions : undefined;
|
|
111
111
|
initialState: Record<string, any>;
|
|
112
112
|
isClient: boolean;
|
|
113
|
-
onSSRAppRendered(cb: Function)
|
|
114
|
-
triggerOnSSRAppRendered(route: string, appHTML: string, appCtx: ViteReactSSGContext)
|
|
115
|
-
transformState
|
|
113
|
+
onSSRAppRendered: (cb: Function) => void;
|
|
114
|
+
triggerOnSSRAppRendered: (route: string, appHTML: string, appCtx: ViteReactSSGContext) => Promise<unknown[]>;
|
|
115
|
+
transformState?: (state: any) => any;
|
|
116
116
|
/**
|
|
117
117
|
* Current router path on SSG, `undefined` on client side.
|
|
118
118
|
*/
|