iles
Version:
Vite & Vue powered static site generator with partial hydration
84 lines (81 loc) • 3.31 kB
JavaScript
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
};