vite-react-ssg 0.6.0 → 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/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.d734eb79.js';
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, bold, reset, bgLightCyan } from 'kolorist';
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,13 +854,21 @@ 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 (const route of routes2) {
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
- if (route.getStaticPaths && path?.includes(":")) {
871
+ if (route.getStaticPaths && isDynamicSegmentsRoute(path)) {
867
872
  const staticPaths = await route.getStaticPaths();
868
873
  for (let staticPath of staticPaths) {
869
874
  staticPath = handlePath(staticPath, prefix, route.entry);
@@ -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, lazyPaths: Array.from(lazyPaths) };
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,9 +929,11 @@ 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, "");
932
+ const dynamicRE = /[:*?]/;
933
+ function isDynamicSegmentsRoute(route) {
934
+ if (!route)
935
+ return false;
936
+ return dynamicRE.test(route);
957
937
  }
958
938
 
959
939
  async function getCritters(outDir, options = {}) {
@@ -1048,17 +1028,6 @@ async function render(routesOrApp, request, styleCollector, basename) {
1048
1028
  const { htmlAttributes, bodyAttributes, metaAttributes, styleTag } = extractHelmet(helmetContext, styleCollector);
1049
1029
  return { appHTML, htmlAttributes, bodyAttributes, metaAttributes, styleTag, routerContext: context };
1050
1030
  }
1051
- async function preLoad(routes, paths) {
1052
- if (!paths || paths.length === 0)
1053
- return routes;
1054
- const { createStaticHandler } = await import('react-router-dom/server.js');
1055
- const { dataRoutes, query } = createStaticHandler(routes);
1056
- await Promise.all(paths.map(async (path) => {
1057
- const request = createRequest(path);
1058
- return query(request);
1059
- }));
1060
- return dataRoutes;
1061
- }
1062
1031
  function extractHelmet(context, styleCollector) {
1063
1032
  const { helmet } = context;
1064
1033
  const htmlAttributes = helmet.htmlAttributes.toString();
@@ -1074,56 +1043,6 @@ function extractHelmet(context, styleCollector) {
1074
1043
  return { htmlAttributes, bodyAttributes, metaAttributes, styleTag };
1075
1044
  }
1076
1045
 
1077
- function renderPreloadLinks(document, modules, ssrManifest) {
1078
- const seen = /* @__PURE__ */ new Set();
1079
- const preloadLinks = [];
1080
- Array.from(modules).forEach((id) => {
1081
- const files = ssrManifest[id] || [];
1082
- files.forEach((file) => {
1083
- if (!preloadLinks.includes(file))
1084
- preloadLinks.push(file);
1085
- });
1086
- });
1087
- if (preloadLinks) {
1088
- preloadLinks.forEach((file) => {
1089
- if (!seen.has(file)) {
1090
- seen.add(file);
1091
- renderPreloadLink(document, file);
1092
- }
1093
- });
1094
- }
1095
- }
1096
- function renderPreloadLink(document, file) {
1097
- if (file.endsWith(".js")) {
1098
- appendLink(document, {
1099
- rel: "modulepreload",
1100
- crossOrigin: "",
1101
- href: file
1102
- });
1103
- } else if (file.endsWith(".css")) {
1104
- appendLink(document, {
1105
- rel: "stylesheet",
1106
- href: file
1107
- });
1108
- }
1109
- }
1110
- function createLink$1(document) {
1111
- return document.createElement("link");
1112
- }
1113
- function setAttrs(el, attrs) {
1114
- const keys = Object.keys(attrs);
1115
- for (const key of keys)
1116
- el.setAttribute(key, attrs[key]);
1117
- }
1118
- function appendLink(document, attrs) {
1119
- const exits = document.head.querySelector(`link[href='${attrs.file}']`);
1120
- if (exits)
1121
- return;
1122
- const link = createLink$1(document);
1123
- setAttrs(link, attrs);
1124
- document.head.appendChild(link);
1125
- }
1126
-
1127
1046
  async function renderHTML({
1128
1047
  rootContainerId,
1129
1048
  indexHTML,
@@ -1177,10 +1096,61 @@ async function detectEntry(root) {
1177
1096
  }) || [];
1178
1097
  return entry || "src/main.ts";
1179
1098
  }
1180
- function createLink(href) {
1099
+ function createLink$1(href) {
1181
1100
  return `<link rel="stylesheet" href="${href}">`;
1182
1101
  }
1183
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
+
1184
1154
  function DefaultIncludedRoutes(paths, _routes) {
1185
1155
  return paths.filter((i) => !i.includes(":") && !i.includes("*"));
1186
1156
  }
@@ -1262,9 +1232,7 @@ async function build(ssgOptions = {}, viteConfig = {}) {
1262
1232
  const { createRoot, includedRoutes: serverEntryIncludedRoutes } = format === "esm" ? await import(serverEntry) : _require(serverEntry);
1263
1233
  const includedRoutes = serverEntryIncludedRoutes || configIncludedRoutes;
1264
1234
  const { routes } = await createRoot(false);
1265
- const { lazyPaths } = await routesToPaths(routes);
1266
- const dataRoutes = await preLoad([...routes || []], lazyPaths);
1267
- const { paths, pathToEntry } = await routesToPaths(dataRoutes);
1235
+ const { paths, pathToEntry } = await routesToPaths(routes);
1268
1236
  let routesPaths = includeAllRoutes ? paths : await includedRoutes(paths, routes || []);
1269
1237
  routesPaths = DefaultIncludedRoutes(routesPaths);
1270
1238
  routesPaths = Array.from(new Set(routesPaths));
@@ -1304,8 +1272,10 @@ async function build(ssgOptions = {}, viteConfig = {}) {
1304
1272
  renderPreloadLinks(jsdom.window.document, modules, ssrManifest);
1305
1273
  const html = jsdom.serialize();
1306
1274
  let transformed = await onPageRendered?.(path, html, appCtx) || html;
1307
- if (critters)
1275
+ if (critters) {
1308
1276
  transformed = await crittersQueue.add(() => critters.process(transformed));
1277
+ transformed = transformed.replace(/<link\srel="stylesheet"/g, '<link rel="stylesheet" crossorigin');
1278
+ }
1309
1279
  if (styleTag)
1310
1280
  transformed = transformed.replace("<head>", `<head>${styleTag}`);
1311
1281
  const formatted = await formatHtml(transformed, formatting);
@@ -1355,9 +1325,14 @@ async function formatHtml(html, formatting) {
1355
1325
  minifyCSS: true
1356
1326
  });
1357
1327
  } else if (formatting === "prettify") {
1358
- const prettier = (await import('prettier/esm/standalone.mjs')).default;
1359
- const parserHTML = (await import('prettier/esm/parser-html.mjs')).default;
1360
- return prettier.format(html, { semi: false, parser: "html", plugins: [parserHTML] });
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
+ }
1361
1336
  }
1362
1337
  return html;
1363
1338
  }
@@ -1379,114 +1354,48 @@ function collectModules(manifest, entry, mods = /* @__PURE__ */ new Set()) {
1379
1354
  return mods;
1380
1355
  }
1381
1356
 
1382
- const SHORTCUTS = [
1383
- {
1384
- key: "u",
1385
- description: "show server url",
1386
- action(vite, _) {
1387
- vite.config.logger.info("");
1388
- printServerInfo(vite, true);
1389
- }
1390
- },
1391
- {
1392
- key: "c",
1393
- description: "clear console",
1394
- action(vite, _) {
1395
- vite.config.logger.clearScreen("error");
1396
- }
1397
- },
1398
- {
1399
- key: "q",
1400
- description: "quit",
1401
- action(_, server) {
1402
- server.close(() => process.exit());
1403
- }
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);
1404
1363
  }
1405
- ];
1406
- function bindShortcuts(viteServer, server) {
1407
- if (!process.stdin.isTTY || process.env.CI)
1408
- return;
1409
- viteServer.config.logger.info(
1410
- dim(green(" \u279C")) + dim(" press ") + bold("h") + dim(" to show help")
1411
- );
1412
- const shortcuts = SHORTCUTS;
1413
- let actionRunning = false;
1414
- const onInput = async (input) => {
1415
- if (input === "" || input === "") {
1416
- try {
1417
- await server.close();
1418
- } finally {
1419
- process.exit(1);
1420
- }
1421
- return;
1422
- }
1423
- if (actionRunning)
1424
- return;
1425
- if (input === "h") {
1426
- viteServer.config.logger.info(
1427
- [
1428
- "",
1429
- bold(" Shortcuts"),
1430
- ...shortcuts.map(
1431
- (shortcut2) => dim(" press ") + bold(shortcut2.key) + dim(` to ${shortcut2.description}`)
1432
- )
1433
- ].join("\n")
1434
- );
1435
- }
1436
- const shortcut = shortcuts.find((shortcut2) => shortcut2.key === input);
1437
- if (!shortcut)
1438
- return;
1439
- actionRunning = true;
1440
- await shortcut.action(viteServer, server);
1441
- actionRunning = false;
1442
- };
1443
- process.stdin.setRawMode(true);
1444
- process.stdin.on("data", onInput).setEncoding("utf8").resume();
1445
- server.on("close", () => {
1446
- process.stdin.off("data", onInput).pause();
1447
- });
1448
1364
  }
1449
1365
 
1450
- function baseMiddleware(rawBase) {
1451
- return (req, res, next) => {
1452
- const url = req.url;
1453
- const pathname = cleanUrl(url);
1454
- const base = rawBase;
1455
- if (pathname.startsWith(base))
1456
- return next();
1457
- if (pathname === "/" || pathname === "/index.html") {
1458
- res.writeHead(302, {
1459
- Location: base + url.slice(pathname.length)
1460
- });
1461
- res.end();
1462
- return;
1463
- }
1464
- const redirectPath = withTrailingSlash(url) !== base ? joinUrlSegments(base, url) : base;
1465
- if (req.headers.accept?.includes("text/html")) {
1466
- res.writeHead(404, {
1467
- "Content-Type": "text/html"
1468
- });
1469
- res.end(
1470
- `The server is configured with a public base URL of ${base} - did you mean to visit <a href="${redirectPath}">${redirectPath}</a> instead?`
1471
- );
1472
- } else {
1473
- res.writeHead(404, {
1474
- "Content-Type": "text/plain"
1475
- });
1476
- res.end(
1477
- `The server is configured with a public base URL of ${base} - did you mean to visit ${redirectPath} instead?`
1478
- );
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
+ }
1479
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)
1480
1390
  };
1391
+ return new Request(url.href, init);
1481
1392
  }
1482
1393
 
1483
- async function dev(ssgOptions = {}, viteConfig = {}) {
1394
+ async function dev(ssgOptions = {}, viteConfig = {}, customOptions) {
1484
1395
  const mode = process.env.MODE || process.env.NODE_ENV || ssgOptions.mode || "development";
1485
1396
  const config = await resolveConfig(viteConfig, "serve", mode, mode);
1486
1397
  const cwd = process.cwd();
1487
1398
  const root = config.root || cwd;
1488
- const httpsOptions = config.server.https;
1489
- setBase(config.rawBase);
1490
1399
  const {
1491
1400
  entry = await detectEntry(root),
1492
1401
  onBeforePageRender,
@@ -1498,21 +1407,12 @@ async function dev(ssgOptions = {}, viteConfig = {}) {
1498
1407
  const template = await fs.readFile(join(root, "index.html"), "utf-8");
1499
1408
  let viteServer;
1500
1409
  globalThis.__ssr_start_time = performance.now();
1501
- createServer$1().then(async (app) => {
1502
- const port = viteServer.config.server.port || 5173;
1503
- if (httpsOptions) {
1504
- const localHttpsOptions = typeof httpsOptions === "boolean" ? await certificateFor(["localhost"]) : httpsOptions;
1505
- const server = https.createServer(localHttpsOptions, app);
1506
- server.listen(port, () => {
1507
- printServerInfo(viteServer, false, true);
1508
- bindShortcuts(viteServer, server);
1509
- });
1510
- } else {
1511
- const server = app.listen(port, () => {
1512
- printServerInfo(viteServer);
1513
- bindShortcuts(viteServer, server);
1514
- });
1515
- }
1410
+ createServer$1().catch((err) => {
1411
+ console.error(
1412
+ `${red(`failed to start server. error:`)}
1413
+ ${err.stack}`
1414
+ );
1415
+ process.exit(1);
1516
1416
  });
1517
1417
  async function createServer$1() {
1518
1418
  process.env.__DEV_MODE_SSR = "true";
@@ -1520,108 +1420,103 @@ async function dev(ssgOptions = {}, viteConfig = {}) {
1520
1420
  const { jsdomGlobal } = await import('./chunks/jsdomGlobal.mjs');
1521
1421
  jsdomGlobal();
1522
1422
  }
1523
- const app = express();
1524
1423
  viteServer = await createServer({
1525
- // ...options,
1526
- server: { middlewareMode: true },
1527
- appType: "custom"
1528
- });
1529
- app.use(baseMiddleware(getBase()));
1530
- app.use((req, res, next) => {
1531
- viteServer.middlewares.handle(req, res, next);
1532
- });
1533
- app.use("*", async (req, res) => {
1534
- try {
1535
- const url = req.originalUrl;
1536
- const indexHTML = await viteServer.transformIndexHtml(url, template);
1537
- const createRoot = await viteServer.ssrLoadModule(ssrEntry).then((m) => m.createRoot);
1538
- const appCtx = await createRoot(false, url);
1539
- const { routes, getStyleCollector, base: base2, app: app2 } = appCtx;
1540
- const transformedIndexHTML = await onBeforePageRender?.(url, indexHTML, appCtx) || indexHTML;
1541
- const styleCollector = getStyleCollector ? await getStyleCollector() : null;
1542
- const { appHTML, bodyAttributes, htmlAttributes, metaAttributes, styleTag, routerContext } = await render(app2 ?? [...routes], createFetchRequest(req), styleCollector, base2);
1543
- metaAttributes.push(styleTag);
1544
- const matchesEntries = routerContext?.matches.map((match) => match.route.entry).filter((entry2) => !!entry2).map((entry2) => entry2[0] === "/" ? entry2 : `/${entry2}`) ?? [];
1545
- const mods = await Promise.all(
1546
- [entry, ...matchesEntries].map(async (entry2) => await viteServer.moduleGraph.getModuleByUrl(entry2))
1547
- );
1548
- const assetsUrls = /* @__PURE__ */ new Set();
1549
- const collectAssets = async (mod) => {
1550
- if (!mod || !mod?.ssrTransformResult)
1551
- return;
1552
- const { deps = [], dynamicDeps = [] } = mod?.ssrTransformResult;
1553
- const allDeps = [...deps, ...dynamicDeps];
1554
- for (const dep of allDeps) {
1555
- if (dep.endsWith(".css")) {
1556
- assetsUrls.add(dep);
1557
- } else if (dep.endsWith(".ts") || dep.endsWith(".tsx")) {
1558
- const depModule = await viteServer.moduleGraph.getModuleByUrl(dep);
1559
- depModule && await collectAssets(depModule);
1560
- }
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
+ };
1561
1485
  }
1562
- };
1563
- await Promise.all(mods.map(async (mod) => collectAssets(mod)));
1564
- const preloadLink = [...assetsUrls].map((item) => createLink(item));
1565
- metaAttributes.push(...preloadLink);
1566
- const renderedHTML = await renderHTML({
1567
- rootContainerId,
1568
- appHTML,
1569
- indexHTML: transformedIndexHTML,
1570
- metaAttributes,
1571
- bodyAttributes,
1572
- htmlAttributes,
1573
- initialState: null
1574
- });
1575
- const transformed = await onPageRendered?.(url, renderedHTML, appCtx) || renderedHTML;
1576
- res.status(200).set({ "Content-Type": "text/html" }).end(transformed);
1577
- } catch (e) {
1578
- viteServer.ssrFixStacktrace(e);
1579
- console.error(`[vite-react-ssg] error: ${e.stack}`);
1580
- res.status(500).end(e.stack);
1581
- }
1486
+ }
1487
+ ]
1582
1488
  });
1583
- return app;
1489
+ await viteServer.listen();
1490
+ printServerInfo(viteServer, !!customOptions);
1491
+ viteServer.bindCLIShortcuts({ print: true });
1492
+ return viteServer;
1584
1493
  }
1585
1494
  }
1586
- async function printServerInfo(server, onlyUrl = false, https2 = false) {
1495
+ async function printServerInfo(server, onlyUrl = false) {
1496
+ if (onlyUrl)
1497
+ return server.printUrls();
1587
1498
  const info = server.config.logger.info;
1588
- const port = server.config.server.port || 5173;
1589
- const protocol = https2 ? "https" : "http";
1590
- const url = `${protocol}://localhost:${port}/${removeLeadingSlash(getBase())}`;
1591
- if (!onlyUrl) {
1592
- let ssrReadyMessage = " -- SSR";
1593
- if (globalThis.__ssr_start_time) {
1594
- ssrReadyMessage += ` ready in ${reset(bold(`${Math.round(
1595
- // @ts-expect-error global var
1596
- performance.now() - globalThis.__ssr_start_time
1597
- )}ms`))}`;
1598
- }
1599
- info(
1600
- `
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
+ `
1601
1508
  ${bgLightCyan(` VITE-REACT-SSG v${version} `)}`,
1602
- { clear: !server.config.logger.hasWarned }
1603
- );
1604
- info(
1605
- `${cyan(`
1509
+ { clear: !server.config.logger.hasWarned }
1510
+ );
1511
+ info(
1512
+ `${cyan(`
1606
1513
  VITE v${version$1}`) + dim(ssrReadyMessage)}
1607
1514
  `
1608
- );
1609
- }
1515
+ );
1610
1516
  info(
1611
1517
  green(" dev server running at:")
1612
1518
  );
1613
- printUrls(url, info);
1614
- }
1615
- function printUrls(url, info) {
1616
- const colorUrl = (url2) => cyan(url2.replace(/:(\d+)\//, (_, port) => `:${bold(port)}/`));
1617
- info(` ${green("\u279C")} ${bold("Local")}: ${colorUrl(url)}`);
1618
- }
1619
- let base = "";
1620
- function getBase() {
1621
- return base;
1622
- }
1623
- function setBase(newBase) {
1624
- base = newBase;
1519
+ server.printUrls();
1625
1520
  }
1626
1521
 
1627
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): void;
114
- triggerOnSSRAppRendered(route: string, appHTML: string, appCtx: ViteReactSSGContext): Promise<unknown[]>;
115
- transformState?(state: any): any;
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
  */