UNPKG

iles

Version:

Vite & Vue powered static site generator with partial hydration

84 lines (81 loc) 3.31 kB
import { VIRTUAL_PREFIX, VIRTUAL_TURBO_ID } from "./chunk-YHWL6QBB.js"; import { uniq } from "./chunk-PUZAE3UL.js"; import { rebaseImports } from "./chunk-2H4LDK5A.js"; // src/node/build/write.ts import { promises as fs } from "fs"; import { join, resolve, dirname } from "pathe"; import glob from "fast-glob"; async function writePages(config, islandsByPath, { routesToRender }) { const manifest = await parseManifest(config.outDir, islandsByPath); await Promise.all(routesToRender.map(async (route) => await writeRoute(config, manifest, route, islandsByPath[route.path]))); const tempIslandFiles = await glob(join(config.outDir, `**/${VIRTUAL_PREFIX}*.js`)); for (const temp of tempIslandFiles) await fs.unlink(temp); } async function writeRoute(config, manifest, route, islands = []) { let content = route.rendered; if (route.outputFilename.endsWith(".html")) { const preloadScripts = []; for (const island of islands) { const entry = manifest[`${VIRTUAL_PREFIX}${island.entryFilename}`]; if (!entry) { const message = `Unable to find entry for island '${island.entryFilename}' in manifest.json`; console.error(`${message}. Island: `, island, "\n\nManifest:\n", manifest); throw new Error(message); } if (entry.imports) preloadScripts.push(...entry.imports); const filename2 = resolve(config.outDir, entry.file); const code = await fs.readFile(filename2, "utf-8"); const rebasedCode = await rebaseImports(config, code); content = content.replace( `<!--${island.placeholder}-->`, // TODO: Remove additional script tag once Firefox is fixed // https://bugzilla.mozilla.org/show_bug.cgi?id=1737882 () => `<script></script><script type="module" async>${rebasedCode}</script>` ); } route.rendered = content.replace("</head>", () => `${stringifyScripts(config, manifest, preloadScripts)}</head>`); } route = await config.ssg.beforePageRender?.(route, config) || route; const filename = resolve(config.outDir, route.outputFilename); await fs.mkdir(dirname(filename), { recursive: true }); await fs.writeFile(filename, route.rendered, "utf-8"); } function stringifyScripts({ turbo, base }, manifest, hrefs) { return [ turbo && injectNavigation(base, manifest), stringifyPreload(base, manifest, hrefs) ].filter((x) => x).join(""); } function injectNavigation(base, manifest) { const src = manifest[VIRTUAL_TURBO_ID]?.file; return src && `<script type="module" async src="${base}${src}"></script>`; } function stringifyPreload(base, manifest, hrefs) { return uniq(resolveManifestEntries(manifest, hrefs)).map((href) => `<link rel="modulepreload" href="${base}${href}" crossorigin/>`).join(""); } function resolveManifestEntries(manifest, entryNames) { return entryNames.flatMap((entryName) => { const entry = manifest[entryName]; return [entry.file, ...resolveManifestEntries(manifest, entry.imports || [])]; }); } async function parseManifest(outDir, islandsByPath) { const manifestPath = join(outDir, ".vite", "manifest.json"); try { return JSON.parse(await fs.readFile(manifestPath, "utf-8")); } catch (err) { if (Object.keys(islandsByPath).length > 0) throw err; return {}; } } export { writePages };