105 lines
3.2 KiB
JavaScript
105 lines
3.2 KiB
JavaScript
const fs = require("fs");
|
|
const path = require("path");
|
|
const CleanCSS = require("clean-css");
|
|
const { minify } = require("terser");
|
|
|
|
const ROOT_DIR = path.resolve(__dirname, "..");
|
|
const DIST_DIR = path.join(ROOT_DIR, "dist");
|
|
const BASE_CSS_DIR = path.join(ROOT_DIR, "css", "base");
|
|
const THEMES_DIR = path.join(ROOT_DIR, "css", "themes");
|
|
const JS_DIR = path.join(ROOT_DIR, "js");
|
|
|
|
const BASE_CSS_FILES = ["base.css", "alert.css", "buttons.css"];
|
|
const JS_FILES = ["constants.js", "dom.js", "y2k-alert.js", "index.js"];
|
|
|
|
function ensureDir(dirPath) {
|
|
fs.mkdirSync(dirPath, { recursive: true });
|
|
}
|
|
|
|
function readFiles(folder, files) {
|
|
return files
|
|
.map((file) => fs.readFileSync(path.join(folder, file), "utf8"))
|
|
.join("\n\n");
|
|
}
|
|
|
|
function buildCss() {
|
|
const cssMinifier = new CleanCSS({ level: 2 });
|
|
const baseCss = readFiles(BASE_CSS_DIR, BASE_CSS_FILES);
|
|
const themeFolders = fs
|
|
.readdirSync(THEMES_DIR, { withFileTypes: true })
|
|
.filter((entry) => entry.isDirectory())
|
|
.map((entry) => entry.name)
|
|
.sort();
|
|
|
|
themeFolders.forEach((themeName) => {
|
|
const themePath = path.join(THEMES_DIR, themeName);
|
|
const themeFiles = fs
|
|
.readdirSync(themePath)
|
|
.filter((file) => file.endsWith(".css"))
|
|
.sort();
|
|
|
|
const themeCss = readFiles(themePath, themeFiles);
|
|
const output = `${baseCss}\n\n${themeCss}`;
|
|
|
|
const distFile = path.join(DIST_DIR, `y2k-alerts-${themeName}.css`);
|
|
const distMinFile = path.join(DIST_DIR, `y2k-alerts-${themeName}.min.css`);
|
|
const minified = cssMinifier.minify(output);
|
|
|
|
if (minified.errors.length > 0) {
|
|
throw new Error(`CSS minification failed for ${themeName}: ${minified.errors.join(", ")}`);
|
|
}
|
|
|
|
fs.writeFileSync(distFile, output, "utf8");
|
|
fs.writeFileSync(distMinFile, minified.styles, "utf8");
|
|
});
|
|
|
|
const genericFile = path.join(DIST_DIR, "y2k-alerts-generic.css");
|
|
const genericMinFile = path.join(DIST_DIR, "y2k-alerts-generic.min.css");
|
|
|
|
if (fs.existsSync(genericFile)) {
|
|
fs.copyFileSync(genericFile, path.join(DIST_DIR, "y2k-alerts.css"));
|
|
}
|
|
|
|
if (fs.existsSync(genericMinFile)) {
|
|
fs.copyFileSync(genericMinFile, path.join(DIST_DIR, "y2k-alerts.min.css"));
|
|
}
|
|
}
|
|
|
|
async function buildJs() {
|
|
const jsBundle = readFiles(JS_DIR, JS_FILES);
|
|
const distFile = path.join(DIST_DIR, "y2k-alerts.js");
|
|
const distMinFile = path.join(DIST_DIR, "y2k-alerts.min.js");
|
|
const minified = await minify(jsBundle, {
|
|
compress: true,
|
|
mangle: true,
|
|
format: {
|
|
comments: false
|
|
}
|
|
});
|
|
|
|
if (!minified.code) {
|
|
throw new Error("JS minification failed: terser returned empty output.");
|
|
}
|
|
|
|
fs.writeFileSync(distFile, jsBundle, "utf8");
|
|
fs.writeFileSync(distMinFile, minified.code, "utf8");
|
|
}
|
|
|
|
async function build() {
|
|
ensureDir(DIST_DIR);
|
|
buildCss();
|
|
await buildJs();
|
|
console.log("Built y2k-alerts assets in dist/");
|
|
}
|
|
|
|
if (require.main === module) {
|
|
build().catch((error) => {
|
|
console.error(error);
|
|
process.exit(1);
|
|
});
|
|
}
|
|
|
|
module.exports = {
|
|
build
|
|
};
|