UNPKG

domco

Version:

Minimal Full-Stack JavaScript

91 lines (90 loc) 3.71 kB
import { dirNames, fileNames } from "../../constants/index.js"; import { getChunk } from "../../util/manifest/index.js"; import fs from "node:fs/promises"; import path from "node:path"; /** * Creates the `client:page` virtual module. * * @returns Vite plugin */ export const pagePlugin = () => { const pageId = "client:page"; const resolvedPageId = `\0${pageId}`; let devServer; /** Watched page filePaths. */ const watched = new Set(); return { name: `domco:${pageId}`, configureServer(server) { devServer = server; }, resolveId(id) { if (id.startsWith(pageId)) { // don't return the resolved id here, needs to be the full path. return `\0${id}`; } }, async load(id, _options) { if (id.startsWith(resolvedPageId)) { let pathName = id.slice(resolvedPageId.length); // remove trailing slash if (pathName.endsWith("/")) pathName = pathName.slice(0, -1); if (!pathName) pathName = "/"; let chunk; let html; if (devServer) { // read from src and transform const src = path.join(dirNames.src.client, pathName, fileNames.page); chunk = { tags: "", src: { // src relative to src/ src, // this is the html file in prod file: "", // this is a js file in prod, so empty here instead of the html assets: [], module: [], preload: [], style: [], dynamic: [], }, }; // add base const filePath = path.join(dirNames.src.base, src); if (!watched.has(filePath)) { // add listeners if they are not already there watched.add(filePath); devServer.watcher.on("all", (_event, fp) => { if (fp.endsWith(filePath)) { const mod = devServer.moduleGraph.getModuleById(id); if (mod) devServer.reloadModule(mod); } }); } try { html = await fs.readFile(filePath, "utf-8"); html = await devServer.transformIndexHtml(pathName, html); } catch (error) { html = ""; if (error instanceof Error) { this.warn(error.message); } else { this.warn(`Could not read and transform \`${filePath}\``); } } } else { chunk = await getChunk({ pathName, error: this.error, page: true }); // read from client output html = await fs.readFile(path.join(dirNames.out.base, dirNames.out.client.base, dirNames.src.client, pathName, fileNames.page), "utf-8"); } return (`export const html = ${JSON.stringify(html)};\n` + `export const chunk = ${JSON.stringify(chunk)}\n`); } }, }; };