import React from 'react'; import { hydrateRoot, createRoot } from 'react-dom/client'; import { applyTheme, getStoredTheme } from './utils/theme'; import App from './App'; import { consumeHomeBoot } from './utils/homeBoot'; import { beginHomeHydrate } from './utils/homeHydrate'; import { reloadForStaleChunk } from './utils/chunkLoad'; import { ensureColdBootReady, isMainLayoutPath } from './utils/prefetchRoute'; applyTheme(getStoredTheme()); consumeHomeBoot(); // Vite modulepreload / 动态 import 失败(发版后旧 hashed URL 404) window.addEventListener('vite:preloadError', (event) => { event.preventDefault(); reloadForStaleChunk(); }); function hasSSRHome(): boolean { return !!document.querySelector('#root .ssr-home'); } function waitForStylesheets(): Promise { const links = Array.from(document.querySelectorAll('link[rel="stylesheet"]')); if (links.length === 0) return Promise.resolve(); return Promise.all( links.map( (node) => new Promise((resolve) => { const link = node as HTMLLinkElement; try { if (link.sheet) { resolve(); return; } } catch { /* cross-origin */ } const finish = () => resolve(); link.addEventListener('load', finish, { once: true }); link.addEventListener('error', finish, { once: true }); }), ), ).then(() => undefined); } function renderApp() { return ( ); } function mountCreateRoot(el: HTMLElement) { createRoot(el).render(renderApp()); } /** 有 SSR 正文:hydrate 接管同一 DOM;失败则回退 createRoot */ function mountHydrateHome(el: HTMLElement) { beginHomeHydrate(); try { hydrateRoot(el, renderApp()); } catch (err) { console.warn('[j13] hydrateRoot 失败,回退 createRoot', err); el.innerHTML = ''; mountCreateRoot(el); } } async function boot() { const path = `${window.location.pathname}${window.location.search}`; const ssr = hasSSRHome(); await waitForStylesheets(); try { if (document.fonts?.ready) await document.fonts.ready; } catch { /* ignore */ } if (isMainLayoutPath(window.location.pathname)) { await ensureColdBootReady(path); } const root = document.getElementById('root'); if (!root) return; if (ssr) { mountHydrateHome(root); } else { mountCreateRoot(root); } } void boot();