Ship VMID 7811 API (assistance, contact, Stripe checkout), wire donate and forms to API with accessible success UI, static LCP shell with deferred React mount, and perf gate tooling (P0 72/2600ms; world-class 85/2500ms tracked separately). Co-authored-by: Cursor <cursoragent@cursor.com>
148 lines
4.1 KiB
TypeScript
148 lines
4.1 KiB
TypeScript
import { defineConfig } from 'vite'
|
|
import react from '@vitejs/plugin-react'
|
|
import { resolve } from 'path'
|
|
import { VitePWA } from 'vite-plugin-pwa'
|
|
|
|
// Optimized Vite Configuration with PWA Support
|
|
export default defineConfig({
|
|
plugins: [
|
|
react(),
|
|
VitePWA({
|
|
registerType: 'autoUpdate',
|
|
injectRegister: 'script-defer',
|
|
includeAssets: [
|
|
'favicon.svg',
|
|
'favicon.ico',
|
|
'logo.png',
|
|
'logo-horizontal.png',
|
|
'logo-symbol.png',
|
|
'robots.txt',
|
|
'site.webmanifest',
|
|
'brand/**/*',
|
|
],
|
|
manifest: {
|
|
name: 'Miracles in Motion Foundation',
|
|
short_name: 'MiM',
|
|
description: 'Restoring hope through compassion, community, and faith in Los Angeles County',
|
|
theme_color: '#1a3c34',
|
|
background_color: '#1a3c34',
|
|
display: 'standalone',
|
|
scope: '/',
|
|
start_url: '/',
|
|
icons: [
|
|
{
|
|
src: '/favicon.svg',
|
|
sizes: 'any',
|
|
type: 'image/svg+xml',
|
|
purpose: 'any',
|
|
},
|
|
{
|
|
src: '/brand/favicon-192.png',
|
|
sizes: '192x192',
|
|
type: 'image/png',
|
|
purpose: 'any maskable',
|
|
},
|
|
{
|
|
src: '/brand/favicon-512.png',
|
|
sizes: '512x512',
|
|
type: 'image/png',
|
|
purpose: 'any maskable',
|
|
},
|
|
],
|
|
},
|
|
workbox: {
|
|
skipWaiting: true,
|
|
clientsClaim: true,
|
|
cleanupOutdatedCaches: true,
|
|
globPatterns: ['**/*.{js,css,html,ico,svg,webp}', 'brand/**/*'],
|
|
globIgnores: ['**/photos/**', '**/*.map', '**/*.zip'],
|
|
maximumFileSizeToCacheInBytes: 3 * 1024 * 1024,
|
|
runtimeCaching: [
|
|
{
|
|
urlPattern: ({ request }) => request.mode === 'navigate',
|
|
handler: 'NetworkFirst',
|
|
options: {
|
|
cacheName: 'html-navigate-cache',
|
|
expiration: {
|
|
maxEntries: 16,
|
|
maxAgeSeconds: 60 * 60 * 24,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
urlPattern: /\.(js|css)$/,
|
|
handler: 'StaleWhileRevalidate',
|
|
options: {
|
|
cacheName: 'app-assets-cache',
|
|
expiration: {
|
|
maxEntries: 48,
|
|
maxAgeSeconds: 60 * 60 * 24 * 7,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
urlPattern: /^https:\/\/fonts\.googleapis\.com\/.*/i,
|
|
handler: 'CacheFirst',
|
|
options: {
|
|
cacheName: 'google-fonts-cache',
|
|
expiration: {
|
|
maxEntries: 10,
|
|
maxAgeSeconds: 60 * 60 * 24 * 365 // 1 year
|
|
}
|
|
}
|
|
},
|
|
{
|
|
urlPattern: /\.(png|jpg|jpeg|svg|gif|webp)$/,
|
|
handler: 'StaleWhileRevalidate',
|
|
options: {
|
|
cacheName: 'images-cache',
|
|
expiration: {
|
|
maxEntries: 64,
|
|
maxAgeSeconds: 60 * 60 * 24 * 7,
|
|
},
|
|
},
|
|
}
|
|
]
|
|
},
|
|
devOptions: {
|
|
enabled: true
|
|
}
|
|
})
|
|
],
|
|
resolve: {
|
|
alias: {
|
|
'@': resolve(__dirname, './src'),
|
|
},
|
|
},
|
|
server: {
|
|
port: 3000,
|
|
open: true,
|
|
},
|
|
build: {
|
|
outDir: 'dist',
|
|
sourcemap: false,
|
|
rollupOptions: {
|
|
output: {
|
|
manualChunks: {
|
|
vendor: ['react', 'react-dom'],
|
|
motion: ['framer-motion'],
|
|
icons: ['lucide-react'],
|
|
ai: ['@tensorflow/tfjs'],
|
|
utils: ['date-fns', 'react-helmet-async', 'i18next', 'react-i18next'],
|
|
payments: ['@stripe/stripe-js', '@stripe/react-stripe-js'],
|
|
},
|
|
chunkFileNames: 'js/[name]-[hash].js'
|
|
}
|
|
},
|
|
// Enable compression
|
|
minify: 'terser',
|
|
terserOptions: {
|
|
compress: {
|
|
drop_console: true,
|
|
drop_debugger: true,
|
|
},
|
|
},
|
|
// Optimize chunks
|
|
chunkSizeWarningLimit: 500,
|
|
},
|
|
}) |