app/vite.config.ts

127 lines
3.5 KiB
TypeScript

import { defineConfig, loadEnv } from 'vite'
import react from '@vitejs/plugin-react'
import { VitePWA } from 'vite-plugin-pwa'
import path from 'path'
// https://vitejs.dev/config/
export default defineConfig(({ mode }) => {
// Load env file based on mode (development, production, etc.)
// This loads .env.development for dev mode
const env = loadEnv(mode, process.cwd(), '')
// Check if we're behind an SSL proxy
const isSSLProxy = env.VITE_FRONTEND_SITE_URL?.startsWith('https://')
// Determine client-side env vars to expose
const envPrefix = 'VITE_'
const clientEnv = Object.fromEntries(
Object.entries(env)
.filter(([key]) => key.startsWith(envPrefix))
.map(([key, value]) => [`import.meta.env.${key}`, JSON.stringify(value)])
)
return {
plugins: [
react(),
VitePWA({
registerType: 'autoUpdate',
injectRegister: 'inline',
strategies: 'injectManifest',
srcDir: 'src',
filename: 'sw.ts',
devOptions: {
enabled: true,
type: 'module',
},
injectManifest: {
// Allow larger bundles to be precached by the service worker
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024, // 5 MiB
},
manifest: {
name: 'Classroom Copilot',
short_name: 'Classroom Copilot',
description: 'AI-powered teaching assistant',
theme_color: '#ffffff',
background_color: '#ffffff',
display: 'standalone',
scope: '/',
start_url: '/',
icons: [
{
src: '/icons/icon-192x192.png',
sizes: '192x192',
type: 'image/png',
},
{
src: '/icons/icon-512x512.png',
sizes: '512x512',
type: 'image/png',
},
{
src: '/icons/icon-192x192-maskable.png',
sizes: '192x192',
type: 'image/png',
purpose: 'maskable',
},
{
src: '/icons/icon-512x512-maskable.png',
sizes: '512x512',
type: 'image/png',
purpose: 'maskable',
},
],
},
workbox: {
globPatterns: ['**/*.{js,css,html,ico,png,svg,json,vue,txt,woff2}'],
cleanupOutdatedCaches: true,
clientsClaim: true,
skipWaiting: true,
},
}),
],
// Define client-side env vars
define: {
...clientEnv,
// Explicitly define VITE_DEV for runtime checks
'import.meta.env.VITE_DEV': JSON.stringify(env.VITE_DEV || 'false'),
'import.meta.env.DEV': mode === 'development',
'import.meta.env.PROD': mode === 'production',
},
server: {
host: '0.0.0.0',
port: parseInt(env.VITE_PORT_FRONTEND || '5173'),
strictPort: true,
// HMR configuration for SSL proxy
hmr: isSSLProxy ? {
// When behind SSL proxy, use WSS and public host
protocol: 'wss',
host: '192.168.0.94',
port: 5173,
clientPort: 5173,
} : {
// Direct HTTP development
protocol: 'ws',
host: '192.168.0.94',
port: parseInt(env.VITE_PORT_FRONTEND_HMR || '5173'),
},
// Allow all origins for development
cors: true,
},
build: {
outDir: 'dist',
sourcemap: mode === 'development',
},
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
}
})