Files
miracles_in_motion/vite.config.ts
T
defiQUGandCursor 6c0de165d3 P0: mim-api, live conversion paths, and CWV sprint to ~2.56s LCP.
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>
2026-06-15 23:42:45 -07:00

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,
},
})