3DS-RPC/templates/scripts/build.js
Spotlight 1fa2402d0a
Migrate client into 3DS-RPC/3DS-RPC-Desktop
Minimal changes have been to flatten the `server/` subdirectory to the root of the repository. More testing will be required.
2025-04-03 22:06:10 -05:00

106 lines
3.7 KiB
JavaScript

import autoprefixer from "autoprefixer";
import fs from "fs/promises";
import path from "path";
import postcss from "postcss";
import prettier from "prettier";
import pug from "pug";
import * as sass from "sass";
import url from "url";
// A few common paths used throughout our script.
// We expect ./scripts/build.js, thus our base directory `.` is `../..`.
const basePath = url.fileURLToPath(import.meta.resolve("../"));
const srcPath = path.resolve(basePath, "./src");
const staticPath = path.resolve(basePath, "../static");
////////////
// Assets //
////////////
console.log(`### INFO: Copying static assets...`);
const sourceAssets = path.resolve(srcPath, "./assets");
const staticAssets = path.resolve(staticPath, "./assets");
await fs.cp(sourceAssets, staticAssets, { recursive: true });
console.log(`### INFO: Copying static JavaScript...`);
const sourceScripts = path.resolve(srcPath, "./js");
const staticScripts = path.resolve(staticPath, "./js");
await fs.cp(sourceScripts, staticScripts, { recursive: true });
//////////
// SCSS //
//////////
console.log(`### INFO: Rendering SCSS...`);
const sourceStylePath = path.resolve(srcPath, "./scss/styles.scss");
const compiledStyle = sass.compile(sourceStylePath, {
// We enable Node.js package resolution for usage with Bootstrap.
importers: [new sass.NodePackageImporter()],
// TODO: Bootstrap does not currently utilize the Sass module system.
// We sadly must silence the deprecation for @import,
// alongside Bootstrap's own usage of @import (`quietDeps`).
//
// For more information regarding the @import deprecation:
// https://sass-lang.com/documentation/breaking-changes/import/
silenceDeprecations: ["import"],
quietDeps: true,
});
const processedStyle = await postcss()
.use(autoprefixer)
.process(compiledStyle.css, { from: "styles.css", to: "styles.css" });
// Log processing warnings if necessary.
processedStyle.warnings().forEach((warn) => {
console.warn(warn.toString());
});
// Write and saved our processed CSS.
const staticCssDir = path.resolve(staticPath, "./css");
await fs.mkdir(staticCssDir, { recursive: true });
const staticStylePath = path.resolve(staticCssDir, "./styles.css");
await fs.writeFile(staticStylePath, processedStyle.css, "utf8");
////////////////////
// HTML Templates //
////////////////////
const sourceTemplateDir = path.resolve(srcPath, "./pug/pages");
const sourceTemplates = await fs.readdir(sourceTemplateDir);
// Ensure our output directory exists.
const destTemplateDir = path.resolve(basePath, "./dist");
await fs.mkdir(destTemplateDir, { recursive: true });
for (const sourceTemplatePath of sourceTemplates) {
// Ensure we only handle *.pug files.
const templateName = path.basename(sourceTemplatePath);
if (!templateName.endsWith(".pug")) {
continue;
}
// We output from src/pug/pages/*.pug to dist/*.html.
const outputName = templateName.replace(".pug", ".html");
const sourcePath = path.resolve(sourceTemplateDir, templateName);
const destPath = path.resolve(destTemplateDir, outputName);
console.log(`### INFO: Rendering ${sourcePath} to ${destPath}...`);
// First, render via Pug.
const renderedHtml = pug.renderFile(sourcePath, {
doctype: "html",
filename: templateName,
basedir: sourceTemplateDir,
});
// Next, beautify its source.
const prettifiedHtml = await prettier.format(renderedHtml, {
printWidth: 1000,
tabWidth: 4,
singleQuote: true,
proseWrap: "preserve",
endOfLine: "lf",
parser: "html",
htmlWhitespaceSensitivity: "ignore",
});
// We're done!
await fs.writeFile(destPath, prettifiedHtml, "utf-8");
}