iles
Version:
Vite & Vue powered static site generator with partial hydration
60 lines (57 loc) • 2.44 kB
JavaScript
import {
getRoutesToRender
} from "./chunk-KEFRTHOQ.js";
import {
withSpinner
} from "./chunk-PUZAE3UL.js";
// src/node/build/render.ts
import { existsSync } from "fs";
import { join } from "pathe";
import { renderSSRHead } from "@unhead/ssr";
import { renderers } from "@islands/prerender";
import { renderToString } from "vue/server-renderer";
var commentsRegex = /<!--\[-->|<!--]-->|<!---->/g;
async function renderPages(config, islandsByPath, { clientResult }) {
const appPath = ["js", "mjs", "cjs"].map((ext) => join(config.tempDir, `app.${ext}`)).find(existsSync);
if (!appPath)
throw new Error(`Could not find the SSR build for the app in ${config.tempDir}`);
const { createApp } = await import(`file://${appPath}`);
const routesToRender = await withSpinner("resolving static paths", async () => await getRoutesToRender(config, createApp));
const clientChunks = clientResult.output;
await withSpinner("rendering pages", async () => {
for (const route of routesToRender)
route.rendered = await renderPage(config, islandsByPath, clientChunks, route, createApp);
});
return { routesToRender };
}
async function renderPage(config, islandsByPath, clientChunks, route, createApp) {
const { app, head } = await createApp({ routePath: route.path, ssrProps: route.ssrProps });
let content = await renderToString(app, { islandsByPath, renderers });
content = content.replace(commentsRegex, "");
if (!route.outputFilename.endsWith(".html"))
return content;
const { headTags, htmlAttrs, bodyTagsOpen, bodyTags, bodyAttrs } = await renderSSRHead(head);
return `<!DOCTYPE html>
<html ${htmlAttrs}>
<head>
${headTags}
${stylesheetTagsFrom(config, clientChunks)}
${await scriptTagsFrom(config, islandsByPath[route.path])}
</head>
<body ${bodyAttrs}>
${bodyTagsOpen}<div id="app">${content}</div>${bodyTags}
</body>
</html>`;
}
function stylesheetTagsFrom(config, clientChunks) {
return clientChunks.filter((chunk) => chunk.type === "asset" && chunk.fileName.endsWith(".css")).map((chunk) => `<link rel="stylesheet" href="${config.base}${chunk.fileName}">`).join("\n");
}
async function scriptTagsFrom(config, islands) {
const anySolid = islands?.some((island) => island.script.includes("@islands/hydration/solid"));
if (!anySolid) return "";
return "<script>window._$HY={events:[],completed:new WeakSet(),r:{}}</script>";
}
export {
renderPages,
renderPage
};