Files
homepage/svelte.config.js
T
Alexander 8bd794bccb perf(build): replace adapter precompress with a parallel, filtered step
adapter-node's `precompress: true` brotli-q11 + gzips every file in
build/client single-threaded — ~150 MB including 91 MB of already-
compressed media (zero gain) and tens of MB of server-only data — adding
minutes to the build. The worst offenders were ML embedding JSONs
(nutrition 35 MB + bls 20 MB + shopping ~4 MB) that are `?url`-imported by
$lib/server/{nutritionMatcher,shoppingCategorizer}.ts and read server-side
via SvelteKit's read(); no browser ever fetches them, so compressing them
is pure waste.

- svelte.config.js: precompress: false.
- scripts/precompress.ts: postbuild step that only compresses text asset
  types, skips binaries and server-only data (bible TSVs by name, embedding
  JSONs by hashed-name pattern), tunes brotli quality down for large files,
  runs gzip+brotli in parallel, and never writes a larger-than-original or
  duplicate sibling.
- package.json: run precompress after build-error-page with
  UV_THREADPOOL_SIZE=12 so the async compression actually parallelizes.
- Delete static/allioli.json: 20 MB, unreferenced anywhere in the repo.
2026-06-01 16:11:52 +02:00

63 lines
2.7 KiB
JavaScript

import adapter from '@sveltejs/adapter-node';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
import { mdsvex } from 'mdsvex';
/** @type {import('@sveltejs/kit').Config} */
const config = {
extensions: ['.svelte', '.svx'],
preprocess: [
vitePreprocess(),
mdsvex({
extensions: ['.svx'],
layout: {
hike: 'src/lib/components/hikes/HikeMdxLayout.svelte'
}
})
],
kit: {
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
adapter: adapter({
// Precompression is handled by scripts/precompress.ts in postbuild.
// The adapter's own precompress is single-threaded and brotli-q11s every
// file in build/client — including ~90 MB of already-compressed media and
// 20 MB+ text blobs — adding minutes to the build for no gain. Our step is
// parallel, skips binaries, and tunes brotli quality by size.
precompress: false
}),
prerender: {
// The only intentionally-static pages are /hikes (prerender=true) and
// the /errors/[status] set (via that route's EntryGenerator). With the
// crawler on, it follows the global nav out of /hikes and tries to
// prerender the whole dynamic, DB-/ML-backed app — which runs the
// forked prerender worker out of heap (ERR_WORKER_OUT_OF_MEMORY) and
// fails the build. Disable crawling: the prerendered set is then driven
// entirely by `prerender = true` + EntryGenerator.
crawl: false,
handleHttpError: ({ path, message }) => {
// Defensive: hike image binaries live in `hikes-assets/`, outside
// `/static` (nginx serves them in prod, a Vite middleware in dev —
// see vite.config.ts), so the crawler can't fetch them. Harmless
// while crawl is off, but keeps a 404 from failing the build if
// crawling is ever re-enabled.
if (/^\/hikes\/[^/]+\/images\//.test(path)) return;
throw new Error(message);
}
},
alias: {
$models: 'src/models',
$utils: 'src/utils',
$types: 'src/types',
// romcal ships the 1969 bundles inside its workspace dir but does not
// re-export them, so exports-field resolution blocks a direct import. Point
// the scoped package names at the bundle directories so both the TS types
// (index.d.ts) and the ESM entry (esm/index.js) resolve via their package.json.
'@romcal/calendar.general-roman': 'node_modules/romcal/rites/roman1969/dist/bundles/general-roman',
'@romcal/calendar.switzerland': 'node_modules/romcal/rites/roman1969/dist/bundles/switzerland'
}
}
};
export default config;