Files
dylanmazzei-website/build.mjs
T
Alejandro Veras 87f39eb49e Add five consulting service pages
Business Optimization, Supply Chain, Cybersecurity, Education and Fractional
Leadership, with copy verbatim from the content documents and the same layout
as the existing service pages (shared blocks in src/service.mjs). Adds them to
the Consulting menu (now two columns) and footer, restores the Consulting page
links to them, and fixes a mobile overflow from card glows that were not
anchored to their cards.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 12:09:26 -04:00

46 lines
2.4 KiB
JavaScript

// Builds the static site into ./dist. No dependencies: `node build.mjs`.
import { mkdir, rm, writeFile, cp, readFile } from 'node:fs/promises';
import { createHash } from 'node:crypto';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { page, eyebrow, btn } from './src/layout.mjs';
const root = dirname(fileURLToPath(import.meta.url));
const out = join(root, 'dist');
const pages = ['home', 'about', 'portfolio', 'consulting', 'marketing', 'business-setup', 'business-optimization', 'supply-chain', 'cybersecurity', 'education', 'fractional', 'contact', 'press'];
await rm(out, { recursive: true, force: true });
await mkdir(out, { recursive: true });
await cp(join(root, 'static'), out, { recursive: true });
// Fingerprint CSS/JS so a new deploy never reuses a stale cached copy.
const hashOf = async (f) => createHash('sha256').update(await readFile(join(root, 'static', f))).digest('hex').slice(0, 10);
const assetVersions = Object.fromEntries(await Promise.all(['styles.css', 'site.js', 'home.css', 'home.js', 'fonts.css'].map(async (f) => ['/assets/' + f, await hashOf('assets/' + f)])));
const fingerprint = (html) => Object.entries(assetVersions).reduce((h, [u, v]) => h.replaceAll(`"${u}"`, `"${u}?v=${v}"`), html);
const urls = [];
for (const name of pages) {
const def = (await import(`./src/pages/${name}.mjs`)).default;
const file = join(out, def.path, 'index.html');
await mkdir(dirname(file), { recursive: true });
await writeFile(file, fingerprint(page(def)));
urls.push(def.path);
console.log('built', def.path);
}
await writeFile(join(out, '404.html'), fingerprint(page({
path: '/404/',
title: 'Page Not Found | Dylan Mazzei',
description: 'This page could not be found.',
body: `<section class="page-hero"><div class="wrap-narrow stack center" style="align-items:center;text-align:center">${eyebrow('404')}<h1 class="h-display-lg">Page Not Found</h1><div class="btn-row">${btn('BACK TO HOME', '/')}</div></div></section>`,
})));
const today = new Date().toISOString().slice(0, 10);
await writeFile(join(out, 'sitemap.xml'), `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urls.map((u) => ` <url><loc>https://dylanmazzei.com${u}</loc><lastmod>${today}</lastmod></url>`).join('\n')}
</urlset>
`);
await writeFile(join(out, 'robots.txt'), 'User-agent: *\nAllow: /\nSitemap: https://dylanmazzei.com/sitemap.xml\n');
console.log('done →', out);