#!/usr/bin/env node /** * Strip the font formats we do not ship from the bundled Font Awesome 5 CSS. * * assets/fontawesome5/webfonts only contains woff2 + woff, but all.min.css * still advertises eot / ttf / svg fallbacks. A browser that stops at woff * (IE11, older Safari) requests files that were never distributed, so each of * the three styles 404s once per page load. * * The rewrite is scoped to @font-face src: declarations only — glyph rules, * utilities and the license header are left untouched. */ import { readFileSync, writeFileSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; const root = join(dirname(fileURLToPath(import.meta.url)), '..'); const target = join(root, 'assets/fontawesome5/css/all.min.css'); const css = readFileSync(target, 'utf8'); // Each @font-face carries two src statements: the IE-only eot shim // (`src:url(...eot);`) and the formatted source list (`src:url(...),url(...)`). // Match the whole run of consecutive src statements up to the closing brace so // both dangling statements collapse into one clean list. const SHIPPED = new Set(['woff2', 'woff']); const srcRun = /(?:src:[^;{}]*(?:;[^;{}]*?)?)*(?=\})/gi; const rewritten = css.replace(srcRun, (run) => { // Only touch runs that are actually src declarations, not other properties. if (!/^src:/.test(run)) return run; const sources = [...run.matchAll(/url\(([^)]+)\)\s*(?:format\(["']?([a-z0-9-]+)["']?\))?/gi)] .map(([, url, format]) => ({ url: url.trim(), format: (format || '').toLowerCase() })); // Drop every source whose format we do not ship; a source with no format() // is the eot shim, which no browser that loads this file can use. const kept = sources.filter((s) => SHIPPED.has(s.format)); if (!kept.length) return run; const declaration = `src:${kept.map((s) => `url(${s.url}) format("${s.format}")`).join(',')}`; // Already clean: re-running the script must stay a no-op rather than a failure. return declaration === run ? run : declaration; }); const dropped = [...css.matchAll(/url\(([^)]*webfonts[^)]*)\)/g)] .map((m) => m[1]) .filter((url) => !/\.woff2?(\?|\)|$)/.test(url)); const alreadyClean = rewritten === css; if (!alreadyClean) writeFileSync(target, rewritten); if (dropped.length) { console.log(`dropped ${dropped.length} non-shipped font references: ${[...new Set(dropped)].join(', ')}`); } else { console.log('all.min.css already ships only woff2 + woff — nothing to do'); }