You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
160 lines
4.7 KiB
160 lines
4.7 KiB
import { sveltekit } from '@sveltejs/kit/vite'; |
|
import { defineConfig } from 'vite'; |
|
import { execSync } from 'child_process'; |
|
import { SvelteKitPWA } from '@vite-pwa/sveltekit'; |
|
import compression from 'vite-plugin-compression'; |
|
|
|
export default defineConfig({ |
|
plugins: [ |
|
sveltekit(), |
|
compression({ |
|
algorithm: 'gzip', |
|
ext: '.gz', |
|
threshold: 1024, // Compress files > 1KB |
|
}), |
|
compression({ |
|
algorithm: 'brotliCompress', |
|
ext: '.br', |
|
threshold: 1024, |
|
}), |
|
SvelteKitPWA({ |
|
strategies: 'generateSW', |
|
registerType: 'autoUpdate', |
|
workbox: { |
|
globPatterns: ['**/*.{js,css,html,ico,png,svg,woff,woff2,webp,avif}'], |
|
runtimeCaching: [ |
|
{ |
|
urlPattern: /^https:\/\/.*\.(?:png|jpg|jpeg|svg|gif|webp|avif)$/i, |
|
handler: 'CacheFirst', |
|
options: { |
|
cacheName: 'images-cache', |
|
expiration: { |
|
maxEntries: 200, |
|
maxAgeSeconds: 60 * 60 * 24 * 30 // 30 days |
|
} |
|
} |
|
}, |
|
{ |
|
// Cache API responses (relay responses) with cache-first strategy for slow connections |
|
urlPattern: /^wss?:\/\//i, |
|
handler: 'CacheFirst', |
|
options: { |
|
cacheName: 'api-cache', |
|
expiration: { |
|
maxEntries: 200, // Increased from 50 |
|
maxAgeSeconds: 60 * 60 * 24 // 24 hours instead of 5 minutes (optimized for slow connections) |
|
} |
|
} |
|
}, |
|
{ |
|
// Cache static assets with stale-while-revalidate for better performance |
|
urlPattern: /\.(?:js|css|woff|woff2)$/i, |
|
handler: 'StaleWhileRevalidate', |
|
options: { |
|
cacheName: 'static-assets', |
|
expiration: { |
|
maxEntries: 100, |
|
maxAgeSeconds: 60 * 60 * 24 * 7 // 7 days |
|
} |
|
} |
|
}, |
|
{ |
|
// Cache HTML pages with network-first for freshness |
|
urlPattern: /\.html$/i, |
|
handler: 'NetworkFirst', |
|
options: { |
|
cacheName: 'html-cache', |
|
expiration: { |
|
maxEntries: 20, |
|
maxAgeSeconds: 60 * 60 * 24 // 1 day |
|
}, |
|
networkTimeoutSeconds: 2 |
|
} |
|
} |
|
] |
|
}, |
|
manifest: { |
|
name: 'aitherboard - Decentralized Messageboard on Nostr', |
|
short_name: 'aitherboard', |
|
description: 'A decentralized messageboard built on the Nostr protocol. Create threads, comment, react, and zap in a censorship-resistant environment.', |
|
theme_color: '#f1f5f9', |
|
background_color: '#ffffff', |
|
display: 'standalone', |
|
icons: [ |
|
{ |
|
src: 'favicon.ico', |
|
sizes: '64x64', |
|
type: 'image/x-icon' |
|
}, |
|
{ |
|
src: 'apple-touch-icon-180x180.png', |
|
sizes: '180x180', |
|
type: 'image/png', |
|
purpose: 'any maskable' |
|
}, |
|
{ |
|
src: 'apple-touch-icon-152x152.png', |
|
sizes: '152x152', |
|
type: 'image/png' |
|
}, |
|
{ |
|
src: 'apple-touch-icon-144x144.png', |
|
sizes: '144x144', |
|
type: 'image/png' |
|
}, |
|
{ |
|
src: 'apple-touch-icon-120x120.png', |
|
sizes: '120x120', |
|
type: 'image/png' |
|
}, |
|
{ |
|
src: 'apple-touch-icon-114x114.png', |
|
sizes: '114x114', |
|
type: 'image/png' |
|
} |
|
] |
|
}, |
|
devOptions: { |
|
enabled: false |
|
} |
|
}), |
|
{ |
|
name: 'generate-healthz', |
|
buildStart() { |
|
try { |
|
execSync('node scripts/generate-healthz.js', { stdio: 'inherit' }); |
|
} catch (error) { |
|
console.warn('Failed to generate healthz.json:', error); |
|
} |
|
} |
|
} |
|
], |
|
server: { |
|
port: 5173, |
|
strictPort: false |
|
}, |
|
build: { |
|
target: 'esnext', |
|
sourcemap: false, |
|
manifest: false, |
|
minify: 'terser', |
|
terserOptions: { |
|
compress: { |
|
drop_console: ['log', 'debug'], // Remove console.log and console.debug in production, keep error/warn |
|
passes: 2, // Multiple passes for better compression |
|
} |
|
}, |
|
rollupOptions: { |
|
onwarn(warning, warn) { |
|
// Suppress warning about highlight.js default import - it's used in reactive contexts that Vite can't detect |
|
if (warning.message && |
|
typeof warning.message === 'string' && |
|
warning.message.includes('highlight.js') && |
|
warning.message.includes('never used')) { |
|
return; |
|
} |
|
warn(warning); |
|
} |
|
} |
|
} |
|
});
|
|
|