diff --git a/src/main.tsx b/src/main.tsx index fa6ab4d8..46f5b62d 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -2,6 +2,24 @@ import { createRoot } from "react-dom/client"; import App from "./App.tsx"; import "./index.css"; +// Suprimir errores de extensiones del navegador (no críticos) +if (typeof window !== 'undefined') { + const originalError = console.error; + console.error = (...args: any[]) => { + // Filtrar errores de extensiones del navegador + const message = args[0]?.toString() || ''; + if ( + message.includes('message channel closed') || + message.includes('runtime.lastError') || + message.includes('Extension context invalidated') + ) { + // Silenciar estos errores (son de extensiones del navegador, no de nuestra app) + return; + } + originalError.apply(console, args); + }; +} + // CRÍTICO: Desregistrar Service Worker en desarrollo ANTES de cualquier otra cosa // Esto evita que el SW intercepte peticiones de Vite HMR if ('serviceWorker' in navigator) { @@ -102,4 +120,26 @@ if ('serviceWorker' in navigator) { } } -createRoot(document.getElementById("root")!).render(); +// Asegurar que React está disponible antes de renderizar +const rootElement = document.getElementById("root"); +if (!rootElement) { + throw new Error("Root element not found"); +} + +// Renderizar la app +// Nota: Si ves errores de "useLayoutEffect", puede ser un problema de code splitting. +// Asegúrate de que vendor-react se carga antes que otros chunks. +try { + createRoot(rootElement).render(); +} catch (error) { + console.error('[React] Error rendering app:', error); + // Mostrar mensaje de error amigable + rootElement.innerHTML = ` +
+

Error al cargar la aplicación

+

Por favor, recarga la página. Si el problema persiste, limpia la caché del navegador.

+

Error: ${error instanceof Error ? error.message : String(error)}

+
+ `; + throw error; +} diff --git a/vite.config.ts b/vite.config.ts index 26ad989d..788e121e 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -50,10 +50,11 @@ export default defineConfig({ // Separar node_modules en chunks por librería if (id.includes('node_modules')) { // React y React DOM juntos (crítico, cargar primero) - if (id.includes('react') || id.includes('react-dom')) { + // IMPORTANTE: Debe ser el primer chunk para evitar errores de useLayoutEffect + if (id.includes('react') || id.includes('react-dom') || id.includes('scheduler')) { return 'vendor-react'; } - // React Router (crítico para navegación) + // React Router (crítico para navegación, depende de React) if (id.includes('react-router')) { return 'vendor-router'; } @@ -61,43 +62,44 @@ export default defineConfig({ if (id.includes('react-markdown') || id.includes('remark') || id.includes('rehype') || id.includes('unified') || id.includes('micromark') || id.includes('mdast')) { return 'vendor-markdown'; } - // Radix UI (componentes UI, agrupar) + // Radix UI (componentes UI, agrupar, depende de React) if (id.includes('@radix-ui')) { return 'vendor-ui'; } - // TanStack Query + // TanStack Query (depende de React) if (id.includes('@tanstack')) { return 'vendor-query'; } - // Icons (lucide-react) + // Icons (lucide-react, depende de React) if (id.includes('lucide-react')) { return 'vendor-icons'; } - // Charts (recharts, si se usa) + // Charts (recharts, si se usa, depende de React) if (id.includes('recharts')) { return 'vendor-charts'; } - // Formularios (react-hook-form, zod) + // Formularios (react-hook-form, zod, depende de React) if (id.includes('react-hook-form') || id.includes('zod') || id.includes('@hookform')) { return 'vendor-forms'; } - // Date/time (date-fns, react-day-picker) + // Date/time (date-fns, react-day-picker, depende de React) if (id.includes('date-fns') || id.includes('react-day-picker')) { return 'vendor-dates'; } - // Carousel (embla) + // Carousel (embla, puede depender de React) if (id.includes('embla')) { return 'vendor-carousel'; } - // Themes (next-themes) + // Themes (next-themes, depende de React) if (id.includes('next-themes')) { return 'vendor-themes'; } - // Sonner (toasts) + // Sonner (toasts, depende de React) if (id.includes('sonner')) { return 'vendor-toasts'; } - // Resto de node_modules pequeños + // Resto de node_modules pequeños (NO incluir nada que dependa de React) + // Si algo aquí usa React, moverlo arriba return 'vendor-other'; }