sitegen/gen.js

76 lines
1.9 KiB
JavaScript
Executable file

import { lstat, mkdir, readdir } from "fs/promises";
import { dirname, join, relative, resolve } from "path";
import { cwd } from "process";
import js from "./transformers/js.js";
import copy from "./transformers/copy.js";
const sitegenConfigPath = join(cwd(), "sitegen.config.js");
/** @type {any} */
let config = {};
try {
await lstat(sitegenConfigPath);
config = await import(sitegenConfigPath);
} catch {}
const inputDirPath = "./src";
const outputDirPath = join(cwd(), "_site");
const transformers = {
".s.js": js,
".s.jsx": js,
".png": copy,
".jpg": copy,
".jpeg": copy,
".avif": copy,
".webp": copy,
".woff": copy,
".woff2": copy,
...(config?.transformers || {}),
};
let built = 0;
/**
* @param {string} path
*/
async function buildFile(path) {
const transformerEnt = Object.entries(transformers).find(([ext]) =>
path.endsWith(ext)
);
if (!transformerEnt) return;
const outputPath = join(outputDirPath, relative(inputDirPath, path));
await mkdir(dirname(outputPath), { recursive: true });
const transformer = transformerEnt[1];
try {
await transformer.build(path, outputPath);
} catch (error) {
console.error(`While building ${path}`);
throw error;
}
built++;
}
/**
* @param {string} dir
* @returns {Promise<void>}
*/
async function buildDir(dir) {
const children = await readdir(dir, { withFileTypes: true });
await Promise.all(
children.map((child) => {
const path = join(dir, child.name);
if (resolve(path) === resolve(outputDirPath)) return;
if (resolve(path) === resolve("node_modules")) return;
if (resolve(path) === resolve(".git")) return;
if (child.isDirectory()) return buildDir(path);
else if (child.isFile()) return buildFile(path);
})
);
}
console.time("build");
await buildDir(inputDirPath);
console.timeEnd("build");
console.info(`Built ${built} files into ${outputDirPath}.`);