pwaLUPMIS2/vite.config.js
ekke 8674ca4df2 Build: stop the lazy geotiff and shapefile chunks loading at startup
vite.config.js splits geotiff and shpjs out so they load only when a user opens
a Cloud-Optimized GeoTIFF or imports a shapefile, but the built index.html
preloaded both on every visit — about 428 kB (152 kB gzipped) nobody had asked
for.

Two separate causes, both visible in the entry chunk's first line:
- it imported Vite's preload helper, used by every dynamic import(), from the
  geotiff chunk. The helper is a virtual module with no node_modules path, so
  Rollup had parked it there; needing it at startup dragged the whole chunk in.
  It now has a chunk of its own, about 1 kB.
- it imported JSZip from the shpjs chunk. JSZip reached the bundle through
  shp-write, which gis-export.js imports for Shapefile export, so it is needed
  at startup whatever happens; filing it under shpjs pulled that chunk in too.
  It is now its own chunk, costing the 31 kB it actually is.

dist/ rebuilt: index.html now preloads vite-helpers and jszip instead.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 13:40:13 +02:00

102 lines
4.3 KiB
JavaScript

/**
* Vite Configuration
*
* Configures:
* - Cross-origin isolation headers (required for OPFS/SQLite)
* - Worker bundling
*/
import { defineConfig } from 'vite';
export default defineConfig({
// Development server configuration
server: {
headers: {
// Required for OPFS (Origin Private File System) access
'Cross-Origin-Opener-Policy': 'same-origin',
'Cross-Origin-Embedder-Policy': 'require-corp',
},
},
// Preview server (npm run preview) configuration
preview: {
headers: {
'Cross-Origin-Opener-Policy': 'same-origin',
'Cross-Origin-Embedder-Policy': 'require-corp',
},
},
// Build configuration
build: {
// Generate source maps for debugging
sourcemap: true,
// Target modern browsers that support OPFS
target: 'esnext',
// Raise the chunk-size warning threshold.
// Rationale: the two largest chunks are unavoidable —
// • openlayers (~535 kB / ~152 kB gzipped) — the OL library itself,
// used app-wide; further splitting just creates more HTTP round-trips
// • sqlite3.wasm (~856 kB) — a runtime WASM binary, not a JS chunk;
// code-splitting does not apply
// 900 kB silences the noise without hiding genuine regressions.
chunkSizeWarningLimit: 900,
rollupOptions: {
output: {
manualChunks(id) {
// pako (zlib) is pulled in by BOTH geotiff and jspdf (via fast-png).
// Without its own chunk, Rollup assigns it to one of them and the two
// chunks reference each other ("Circular chunk: jspdf -> geotiff").
if (id.includes('node_modules/pako/')) return 'pako';
// Vite's preload helper (the `__vitePreload` used by every dynamic
// import()) is a virtual module with no node_modules path, so Rollup
// is free to park it in whichever chunk it likes — it used to land in
// the geotiff chunk. The entry needs the helper at startup, so that
// made the browser preload all ~257 kB of geotiff.js on every visit,
// defeating the lazy rule below. Give the helper a chunk of its own
// (~1 kB) so the entry pulls in only that.
if (id.includes('vite/preload-helper')) return 'vite-helpers';
// JSZip reaches the bundle through shp-write, which src/gis-export.js
// imports statically for Shapefile export — so it is eager whatever
// we do. The old rule filed it under the shpjs chunk (shpjs 6 in fact
// unzips with but-unzip and never touches JSZip), which dragged that
// whole ~171 kB lazy chunk into the startup preload. On its own it
// costs the ~31 kB it actually is.
if (id.includes('node_modules/jszip/')) return 'jszip';
// Turf.js — only needed when the Analysis panel is opened, which
// main.js imports dynamically. Keep it out of the eager bundle.
if (id.includes('node_modules/@turf/')) return 'turf';
// geotiff.js + the OL modules that use it — only needed when the user
// opens a Cloud-Optimized GeoTIFF layer, which MapView.addCOGLayer()
// imports dynamically. Must be tested BEFORE the generic ol/ rule so
// it isn't swallowed into the eagerly-loaded openlayers chunk.
if (id.includes('node_modules/geotiff/') ||
id.includes('node_modules/ol/source/GeoTIFF') ||
id.includes('node_modules/ol/layer/WebGLTile')) return 'geotiff';
if (id.includes('node_modules/ol/')) return 'openlayers';
if (id.includes('node_modules/ol-ext/')) return 'ol-ext';
if (id.includes('node_modules/bootstrap/')) return 'bootstrap';
// shpjs — dynamically imported at runtime (main.js), so this chunk is
// only fetched when the user imports a shapefile. JSZip is no longer
// matched here (see the jszip rule above): it belongs to shp-write,
// and listing it here is what made this chunk load at startup.
if (id.includes('node_modules/shpjs/')) return 'shpjs';
if (id.includes('node_modules/jspdf')) return 'jspdf';
},
},
},
},
// Worker configuration
worker: {
format: 'es',
},
// Dependency optimization
optimizeDeps: {
exclude: ['sqlocal'],
},
});