mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 08:09:18 +02:00
Add biome + rolldown + lightningcss build pipeline for JS/CSS bundling & minification
- package.json with biome, rolldown, lightningcss devDependencies
- biome.json: add CSS formatter support
- scripts/build-css.mjs: lightningcss resolves @import chain, bundles/minifies CSS
- scripts/build-js.mjs: rolldown per-entry JS bundling (no code splitting)
- scripts/build.mjs: orchestrator for both CSS + JS
- scripts/check-build.mjs: staleness checker for CI/deploy guard
- justfile: add build, build-css, build-js, build-install, build-check recipes
- justfile: deploy recipe now runs build before deploy-code
- head.php + form-page.php: use dist/base.min.css instead of style.css
- All controllers + FormBootstrap: reference dist/*.min.{css,js}
- admin footer: load admin.min.js for all admin pages
- repertoire: use public.min.js instead of individual app JS files
- Fix stray '}' syntax error in admin.css line 305
- .gitignore: add app/public/assets/dist/
This commit is contained in:
82
scripts/check-build.mjs
Normal file
82
scripts/check-build.mjs
Normal file
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Quick check: are dist files present and fresh?
|
||||
* Exits 0 if ok, 1 if missing or stale.
|
||||
*
|
||||
* Staleness: any source file newer than the oldest dist file.
|
||||
*/
|
||||
|
||||
import { statSync, existsSync, readdirSync } from "node:fs";
|
||||
import { resolve, dirname } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const root = resolve(__dirname, "..");
|
||||
const distDir = resolve(root, "app/public/assets/dist");
|
||||
|
||||
const distFiles = readdirSync(distDir).filter(
|
||||
(f) => f.endsWith(".min.css") || f.endsWith(".min.js")
|
||||
);
|
||||
|
||||
if (distFiles.length === 0) {
|
||||
console.error("❌ No dist files found. Run: just build");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Check each dist file exists
|
||||
for (const f of distFiles) {
|
||||
if (!existsSync(resolve(distDir, f))) {
|
||||
console.error(`❌ Missing: dist/${f}. Run: just build`);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Check staleness: any source newer than the oldest dist?
|
||||
function walkDir(dir, ext) {
|
||||
const files = [];
|
||||
const entries = readdirSync(dir, { withFileTypes: true });
|
||||
for (const e of entries) {
|
||||
const full = resolve(dir, e.name);
|
||||
if (e.isDirectory() && e.name !== "components") {
|
||||
files.push(...walkDir(full, ext));
|
||||
} else if (e.isFile() && full.endsWith(ext)) {
|
||||
files.push(full);
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
const cssSrcFiles = walkDir(
|
||||
resolve(root, "app/public/assets/css"),
|
||||
".css"
|
||||
).filter((f) => !f.includes("filepond") && !f.includes("modern-normalize"));
|
||||
|
||||
const jsSrcFiles = walkDir(
|
||||
resolve(root, "app/public/assets/js/app"),
|
||||
".js"
|
||||
);
|
||||
|
||||
const srcFiles = [...cssSrcFiles, ...jsSrcFiles];
|
||||
|
||||
const oldestDist = Math.min(
|
||||
...distFiles.map((f) => statSync(resolve(distDir, f)).mtimeMs)
|
||||
);
|
||||
|
||||
let stale = false;
|
||||
for (const f of srcFiles) {
|
||||
try {
|
||||
if (statSync(f).mtimeMs > oldestDist) {
|
||||
console.error(`❌ Stale dist (source newer than output): ${f}`);
|
||||
stale = true;
|
||||
}
|
||||
} catch {
|
||||
// file may not exist (e.g. entry files), skip
|
||||
}
|
||||
}
|
||||
|
||||
if (stale) {
|
||||
console.error("❌ Run: just build");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log("✅ Build output is up to date");
|
||||
Reference in New Issue
Block a user