SSG Build Cache Incremental Invalidation
Speed up static site builds by hashing content inputs per page, reusing unchanged build cache entries, and invalidating only affected pages.
Code
// SSG build cache: invalidate prerender output when page hashes change
import { createHash } from 'node:crypto';
import { readFile, writeFile, mkdir, readdir } from 'node:fs/promises';
async function buildIncremental(pagesDir, cacheDir) {
await mkdir(cacheDir, { recursive: true });
const pages = (await readdir(pagesDir)).filter((f) => f.endsWith('.md'));
let cacheMeta = {};
try {
cacheMeta = JSON.parse(await readFile(cacheDir + '/manifest.json', 'utf8'));
} catch {
cacheMeta = {};
}
const manifest = {};
let rebuilt = 0;
for (const file of pages) {
const raw = await readFile(pagesDir + '/' + file, 'utf8');
const hash = createHash('sha256').update(raw).digest('hex').slice(0, 16);
if (cacheMeta[file] === hash) {
manifest[file] = hash; // 静态内容未变,复用缓存产物
continue;
}
const html = '<article>' + raw.replace(/^# (.*)$/m, '<h1>$1</h1>') + '</article>';
await writeFile(cacheDir + '/' + file.replace(/\.md$/, '.html'), html);
manifest[file] = hash;
rebuilt += 1;
}
await writeFile(cacheDir + '/manifest.json', JSON.stringify(manifest, null, 2));
return { total: pages.length, rebuilt, cached: pages.length - rebuilt };
}
const stats = await buildIncremental('content/pages', 'dist/cache');
console.log('build finished:', stats);Report a problem with this exampleOpens a pre-filled issue on GitHub.