- Introduce cache busting (to circumvent aggressive caching on iOS - but ideal in other contexts as well)

- Change the build process to allow cache busting
- Optimisations to the build process
- Several improvements of UI geared towards mobile experience
-
This commit is contained in:
Josako
2025-09-25 17:28:01 +02:00
parent cc47ce2d32
commit 16ce59ae98
32 changed files with 1538 additions and 899 deletions

View File

@@ -0,0 +1,55 @@
import { promises as fs } from 'node:fs';
import path from 'node:path';
const DIST_DIR = path.resolve(process.cwd(), 'static', 'dist');
const OUT_FILE = path.join(DIST_DIR, 'manifest.json');
const LOGICAL_ENTRIES = [
{ key: 'dist/chat-client.js', base: 'chat-client', exts: ['.js'] },
{ key: 'dist/chat-client.css', base: 'chat-client', exts: ['.css'] },
// Optionally include main entries if referenced via templates in the future
{ key: 'dist/main.js', base: 'main', exts: ['.js'] },
{ key: 'dist/main.css', base: 'main', exts: ['.css'] },
];
function isHashedFile(file, base, ext) {
return file.startsWith(base + '.') && file.endsWith(ext) && file !== base + ext;
}
async function generate() {
const files = await fs.readdir(DIST_DIR);
const manifest = {};
for (const entry of LOGICAL_ENTRIES) {
const matches = [];
for (const ext of entry.exts) {
for (const f of files) {
if (isHashedFile(f, entry.base, ext)) {
matches.push(`dist/${f}`);
}
}
}
if (matches.length === 1) {
manifest[entry.key] = matches[0];
} else if (matches.length > 1) {
const stats = await Promise.all(
matches.map(async m => ({
file: m,
mtime: (await fs.stat(path.join(DIST_DIR, path.basename(m)))).mtimeMs,
}))
);
stats.sort((a, b) => b.mtime - a.mtime);
manifest[entry.key] = stats[0].file;
} else {
manifest[entry.key] = entry.key; // fallback zodat pagina niet breekt
}
}
await fs.writeFile(OUT_FILE, JSON.stringify(manifest, null, 2), 'utf8');
console.log(`[manifest] written: ${OUT_FILE}`);
}
generate().catch(err => {
console.error('[manifest] generation failed:', err);
process.exit(1);
});