From 1939574e0fba0cb29678b90ccca680619e2e5bd8 Mon Sep 17 00:00:00 2001 From: Philip Date: Wed, 28 Jan 2026 18:44:20 -0800 Subject: [PATCH] feat: Migrate to Vite build tool and lazy load components This commit updates the project to use Vite as the build tool, replacing the previous configuration. It also implements lazy loading for the HostView, PlayerView, and SpectatorView components to improve initial load performance. The spectator view's fastest buzzer calculation has been refactored for clarity and type safety. Dependencies have been updated to include Vite and its React plugin. The import maps in index.html have also been adjusted to reflect the new build tool. --- App.tsx | 21 +++++++++++++++------ components/SpectatorView.tsx | 20 +++++++++++--------- index.html | 8 +++++--- package.json | 4 +++- vite.config.ts | 31 ++++++++++--------------------- 5 files changed, 44 insertions(+), 40 deletions(-) diff --git a/App.tsx b/App.tsx index 94495fb..5f78901 100644 --- a/App.tsx +++ b/App.tsx @@ -1,9 +1,11 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, Suspense } from 'react'; import { GameProvider } from './context/GameContext'; -import { HostView } from './components/HostView'; -import { PlayerView } from './components/PlayerView'; -import { SpectatorView } from './components/SpectatorView'; -import { Monitor, Smartphone, LayoutDashboard } from 'lucide-react'; +import { Monitor, Smartphone, LayoutDashboard, Loader2 } from 'lucide-react'; + +// Lazy load components to reduce initial bundle size +const HostView = React.lazy(() => import('./components/HostView').then(module => ({ default: module.HostView }))); +const PlayerView = React.lazy(() => import('./components/PlayerView').then(module => ({ default: module.PlayerView }))); +const SpectatorView = React.lazy(() => import('./components/SpectatorView').then(module => ({ default: module.SpectatorView }))); const App: React.FC = () => { const [view, setView] = useState<'HOST' | 'PLAYER' | 'SPECTATOR'>('SPECTATOR'); @@ -70,7 +72,14 @@ const App: React.FC = () => { {/* Main Content Area */}
- {renderView()} + + +

Loading Quiz Module...

+
+ }> + {renderView()} + diff --git a/components/SpectatorView.tsx b/components/SpectatorView.tsx index a4d0814..46f6da4 100644 --- a/components/SpectatorView.tsx +++ b/components/SpectatorView.tsx @@ -145,15 +145,17 @@ export const SpectatorView: React.FC = () => { // Top 5 Players const topPlayers = [...players].sort((a,b) => b.score - a.score).slice(0, 5); - // Fastest Buzzer Calculation - let fastestPlayer: Player | null = null; - let fastestTime = Infinity; - players.forEach(p => { - if (p.stats.bestReactionTime && p.stats.bestReactionTime < fastestTime) { - fastestTime = p.stats.bestReactionTime; - fastestPlayer = p; + // Fastest Buzzer Calculation using reduce with explicit generic type + const fastestPlayer = players.reduce((best, p) => { + const pTime = p.stats.bestReactionTime; + if (!pTime) return best; + if (!best || !best.stats.bestReactionTime || pTime < best.stats.bestReactionTime) { + return p; } - }); + return best; + }, null); + + const fastestTime = fastestPlayer?.stats.bestReactionTime ?? Infinity; return (
@@ -203,7 +205,7 @@ export const SpectatorView: React.FC = () => {
Fastest Finger
-
{(fastestPlayer as Player)?.name || '-'}
+
{fastestPlayer ? fastestPlayer.name : '-'}
diff --git a/index.html b/index.html index 39af5b8..67e3fb5 100644 --- a/index.html +++ b/index.html @@ -37,7 +37,7 @@ overscroll-behavior: none; } -
- + \ No newline at end of file diff --git a/package.json b/package.json index 6858eaf..e3a1565 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,9 @@ "react-dom": "^19.2.4", "@google/genai": "^1.38.0", "lucide-react": "^0.563.0", - "recharts": "^3.7.0" + "recharts": "^3.7.0", + "vite": "^7.3.1", + "@vitejs/plugin-react": "^5.1.2" }, "devDependencies": { "@types/node": "^22.14.0", diff --git a/vite.config.ts b/vite.config.ts index ee5fb8d..8b9bfd6 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,23 +1,12 @@ -import path from 'path'; -import { defineConfig, loadEnv } from 'vite'; +import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; -export default defineConfig(({ mode }) => { - const env = loadEnv(mode, '.', ''); - return { - server: { - port: 3000, - host: '0.0.0.0', - }, - plugins: [react()], - define: { - 'process.env.API_KEY': JSON.stringify(env.GEMINI_API_KEY), - 'process.env.GEMINI_API_KEY': JSON.stringify(env.GEMINI_API_KEY) - }, - resolve: { - alias: { - '@': path.resolve(__dirname, '.'), - } - } - }; -}); +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], + base: './', // Ensures assets are loaded relatively (e.g., "assets/script.js" instead of "/assets/script.js") + build: { + outDir: 'dist', + emptyOutDir: true, + }, +}); \ No newline at end of file