import { createApp } from 'vue'; import ArcoVue from '@arco-design/web-vue'; import ArcoVueIcon from '@arco-design/web-vue/es/icon'; // eslint-disable-next-line import/no-unresolved import 'uno.css'; import { installGlobalMessageDefaults } from '@/utils/message'; import router from './router'; import store, { useAppStore } from './store'; import i18n, { initPreferredLocale, ensureFullLocaleMessages } from './locale'; import directive from './directive'; import globalProperties from './plugins/globalProperties'; // 全局 Message:可手动关闭;错误/警告默认 8s installGlobalMessageDefaults(); import { bindHeavyPluginsContext, ensureHeavyPlugins, } from './plugins/heavy-plugins'; import { initAuthKeepAlive } from '@/utils/auth-keepalive'; import { installWeChatH5HistoryGuard } from '@/utils/device'; import { installChunkReloadHandlers, reloadOnChunkLoadError } from '@/utils/chunkReload'; import { setAuthToken } from './api/rbac'; import { useRbacUserStore } from '@/store/modules/rbac-user'; import { applyRbacUserToUserStore } from '@/utils/enter-system'; import App from './App.vue'; import '@/assets/style/global.less'; import '@/styles/list-action.less'; import '@/styles/app-button.less'; import '@/styles/dark-mode.less'; if (import.meta.env.DEV) { void import('./mock'); } /** Login / public pages: no VXE/HT on critical path */ const LIGHT_ENTRY_PATHS = [ '/', '/admin', '/login', '/register', '/track/query', '/wechat/register', '/wechat/bind', '/h5', ]; /** Home uses Arco (+ optional echarts); do not block on VXE/HT */ function isHomePath(path: string) { return path === '/home' || path.startsWith('/home/'); } /** H5/微信/查件:纯 Arco,后台预热 VXE/HT 会注入全局 CSS 造成登录页闪乱 */ function isH5LikePath(path: string) { const normalized = path.split('?')[0] || '/'; return ( normalized === '/h5' || normalized.startsWith('/h5/') || normalized.startsWith('/wechat/') || normalized === '/track/query' ); } function isLightEntry(path: string) { const normalized = path.split('?')[0] || '/'; return LIGHT_ENTRY_PATHS.some( (p) => normalized === p || normalized.startsWith(`${p}/`), ); } function routeNeedsHeavyPlugins(path: string) { const normalized = path.split('?')[0] || '/'; if (isLightEntry(normalized) || isHomePath(normalized) || isH5LikePath(normalized)) { return false; } return true; } const app = createApp(App); app.use(ArcoVue, {}); app.use(ArcoVueIcon); app.use(router); installChunkReloadHandlers(); router.onError((error) => { if (reloadOnChunkLoadError(error)) return; throw error; }); app.use(store); useAppStore().hydrateTheme(); app.use(i18n); app.use(directive); app.use(globalProperties); bindHeavyPluginsContext(app, i18n); const rbacAccessToken = localStorage.getItem('rbac_access_token') || localStorage.getItem('rbac_token'); if (rbacAccessToken) { setAuthToken(rbacAccessToken); } router.beforeEach(async (to) => { if (!isLightEntry(to.path)) { void ensureFullLocaleMessages(); } if (routeNeedsHeavyPlugins(to.path)) { await ensureHeavyPlugins(); } }); async function bootstrap() { const entryPath = typeof window !== 'undefined' ? window.location.pathname : '/'; const light = isLightEntry(entryPath); const rbacUserStore = useRbacUserStore(); // F5:本地身份先灌进 userStore;缺 menus 时与 i18n 并行预取 if (rbacUserStore.isLoggedIn && rbacUserStore.userInfo?.id) { applyRbacUserToUserStore(rbacUserStore.userInfo); } if (!light) { rbacUserStore.prefetchCurrentUser(); } await initPreferredLocale(); // Business / home refresh: need full i18n before paint if (!light) { await ensureFullLocaleMessages(); } if (routeNeedsHeavyPlugins(entryPath)) { await ensureHeavyPlugins(); } app.mount('#app'); ;(window as any).__APP_MOUNTED__ = true; installWeChatH5HistoryGuard(router); initAuthKeepAlive(); // 登录页勿预热 VXE/Element:体积大且会注入全局 CSS,和首屏抢带宽 if (isHomePath(entryPath) && !isH5LikePath(entryPath) && !light) { void ensureHeavyPlugins(); } // 等路由就绪 + 浏览器完成首帧绘制后再淡出 boot,避免 mount 瞬间替换抖动 try { await router.isReady(); } catch { /* ignore */ } await new Promise((resolve) => { requestAnimationFrame(() => { requestAnimationFrame(() => resolve()); }); }); ;(window as any).__dismissAppBoot?.(); } void bootstrap();