From c846bb203c9cd0835776a49a22e88b1398c1f716 Mon Sep 17 00:00:00 2001 From: shunli Date: Thu, 12 Mar 2026 21:48:47 +0800 Subject: [PATCH] =?UTF-8?q?perf(P22PROD1-1,P22PROD1-2):=20=E8=B7=AF?= =?UTF-8?q?=E7=94=B1=E6=87=92=E5=8A=A0=E8=BD=BD=E4=B8=8EVite=E5=88=86?= =?UTF-8?q?=E5=8C=85=E6=B6=88=E9=99=A4=E5=A4=A7=E5=8C=85warning?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/common/RoutePageFallback.tsx | 12 +++ client/src/router/index.tsx | 102 ++++++++++-------- client/src/router/lazy/ApprovalRulesPage.ts | 1 + client/src/router/lazy/AssetRegistryPage.ts | 1 + client/src/router/lazy/AuditLogsPage.ts | 1 + client/src/router/lazy/DelegationsPage.ts | 1 + client/src/router/lazy/DepartmentsPage.ts | 1 + client/src/router/lazy/ErpIntegrationPage.ts | 1 + client/src/router/lazy/FeatureFlagsPage.ts | 1 + client/src/router/lazy/InventoryChecksPage.ts | 1 + client/src/router/lazy/InvoicePoolPage.ts | 1 + client/src/router/lazy/LeaveRequestPage.ts | 1 + client/src/router/lazy/MasterDataPage.ts | 1 + client/src/router/lazy/MobileApprovalsPage.ts | 1 + client/src/router/lazy/MobileAssetScanPage.ts | 1 + client/src/router/lazy/MobileCapturePage.ts | 1 + .../router/lazy/NotificationChannelsPage.ts | 1 + client/src/router/lazy/NotificationsPage.ts | 1 + .../src/router/lazy/PurchaseRequestsPage.ts | 1 + .../router/lazy/ReimbursementDetailPage.ts | 1 + client/src/router/lazy/ReimbursementsPage.ts | 1 + client/src/router/lazy/TravelRequestsPage.ts | 1 + client/src/router/lazy/UserManagementPage.ts | 1 + .../src/router/lazy/WorkflowTaskDetailPage.ts | 1 + client/src/router/lazy/WorkflowTasksPage.ts | 1 + client/src/router/lazy/index.ts | 25 +++++ client/vite.config.ts | 89 +++++++++++++++ 27 files changed, 204 insertions(+), 47 deletions(-) create mode 100644 client/src/components/common/RoutePageFallback.tsx create mode 100644 client/src/router/lazy/ApprovalRulesPage.ts create mode 100644 client/src/router/lazy/AssetRegistryPage.ts create mode 100644 client/src/router/lazy/AuditLogsPage.ts create mode 100644 client/src/router/lazy/DelegationsPage.ts create mode 100644 client/src/router/lazy/DepartmentsPage.ts create mode 100644 client/src/router/lazy/ErpIntegrationPage.ts create mode 100644 client/src/router/lazy/FeatureFlagsPage.ts create mode 100644 client/src/router/lazy/InventoryChecksPage.ts create mode 100644 client/src/router/lazy/InvoicePoolPage.ts create mode 100644 client/src/router/lazy/LeaveRequestPage.ts create mode 100644 client/src/router/lazy/MasterDataPage.ts create mode 100644 client/src/router/lazy/MobileApprovalsPage.ts create mode 100644 client/src/router/lazy/MobileAssetScanPage.ts create mode 100644 client/src/router/lazy/MobileCapturePage.ts create mode 100644 client/src/router/lazy/NotificationChannelsPage.ts create mode 100644 client/src/router/lazy/NotificationsPage.ts create mode 100644 client/src/router/lazy/PurchaseRequestsPage.ts create mode 100644 client/src/router/lazy/ReimbursementDetailPage.ts create mode 100644 client/src/router/lazy/ReimbursementsPage.ts create mode 100644 client/src/router/lazy/TravelRequestsPage.ts create mode 100644 client/src/router/lazy/UserManagementPage.ts create mode 100644 client/src/router/lazy/WorkflowTaskDetailPage.ts create mode 100644 client/src/router/lazy/WorkflowTasksPage.ts create mode 100644 client/src/router/lazy/index.ts diff --git a/client/src/components/common/RoutePageFallback.tsx b/client/src/components/common/RoutePageFallback.tsx new file mode 100644 index 00000000..9e6f82fc --- /dev/null +++ b/client/src/components/common/RoutePageFallback.tsx @@ -0,0 +1,12 @@ +import { Spinner } from "../ui/spinner"; + +export function RoutePageFallback() { + return ( +
+
+ + 页面加载中... +
+
+ ); +} diff --git a/client/src/router/index.tsx b/client/src/router/index.tsx index 50d2f9fd..92f697b9 100644 --- a/client/src/router/index.tsx +++ b/client/src/router/index.tsx @@ -1,38 +1,46 @@ +import { Suspense, type ReactNode } from "react"; import { Navigate, Route, Routes } from "react-router-dom"; import { AppShellLayout } from "../layouts/AppShellLayout"; import { AuthLayout } from "../layouts/AuthLayout"; -import { AuditLogsPage } from "../pages/AuditLogsPage"; -import { ApprovalRulesPage } from "../pages/ApprovalRulesPage"; -import { FeatureFlagsPage } from "../pages/FeatureFlagsPage"; -import { ChangePasswordPage } from "../pages/ChangePasswordPage"; import { BudgetsPage } from "../pages/BudgetsPage"; +import { ChangePasswordPage } from "../pages/ChangePasswordPage"; import { DashboardPage } from "../pages/DashboardPage"; -import { DepartmentsPage } from "../pages/DepartmentsPage"; -import { MasterDataPage } from "../pages/MasterDataPage"; -import { DelegationsPage } from "../pages/DelegationsPage"; import { ForbiddenPage } from "../pages/ForbiddenPage"; -import { MobileApprovalsPage } from "../pages/MobileApprovalsPage"; -import { MobileAssetScanPage } from "../pages/MobileAssetScanPage"; -import { MobileCapturePage } from "../pages/MobileCapturePage"; -import { InvoicePoolPage } from "../pages/InvoicePoolPage"; import { LoginPage } from "../pages/LoginPage"; -import { LeaveRequestPage } from "../pages/LeaveRequestPage"; -import { NotificationsPage } from "../pages/NotificationsPage"; -import { NotificationChannelsPage } from "../pages/NotificationChannelsPage"; -import { ErpIntegrationPage } from "../pages/ErpIntegrationPage"; -import { PurchaseRequestsPage } from "../pages/PurchaseRequestsPage"; -import { TravelRequestsPage } from "../pages/TravelRequestsPage"; -import { AssetRegistryPage } from "../pages/AssetRegistryPage"; -import { InventoryChecksPage } from "../pages/InventoryChecksPage"; import { NotFoundPage } from "../pages/NotFoundPage"; import { ProfilePage } from "../pages/ProfilePage"; -import { ReimbursementDetailPage } from "../pages/ReimbursementDetailPage"; -import { ReimbursementsPage } from "../pages/ReimbursementsPage"; -import { UserManagementPage } from "../pages/UserManagementPage"; -import { WorkflowTaskDetailPage } from "../pages/WorkflowTaskDetailPage"; -import { WorkflowTasksPage } from "../pages/WorkflowTasksPage"; +import { RoutePageFallback } from "../components/common/RoutePageFallback"; +import { + ApprovalRulesPage, + AssetRegistryPage, + AuditLogsPage, + DelegationsPage, + DepartmentsPage, + ErpIntegrationPage, + FeatureFlagsPage, + InventoryChecksPage, + InvoicePoolPage, + LeaveRequestPage, + MasterDataPage, + MobileApprovalsPage, + MobileAssetScanPage, + MobileCapturePage, + NotificationChannelsPage, + NotificationsPage, + PurchaseRequestsPage, + ReimbursementDetailPage, + ReimbursementsPage, + TravelRequestsPage, + UserManagementPage, + WorkflowTaskDetailPage, + WorkflowTasksPage, +} from "./lazy"; import { GuestOnly, RequireAuth, RequirePermission } from "./guards"; +function withRouteFallback(node: ReactNode) { + return }>{node}; +} + export function AppRouter() { return ( @@ -82,7 +90,7 @@ export function AppRouter() { path="reimbursements" element={ - + {withRouteFallback()} } /> @@ -91,7 +99,7 @@ export function AppRouter() { path="reimbursements/:reimbursementId" element={ - + {withRouteFallback()} } /> @@ -100,7 +108,7 @@ export function AppRouter() { path="leave-requests" element={ - + {withRouteFallback()} } /> @@ -109,7 +117,7 @@ export function AppRouter() { path="purchase-requests" element={ - + {withRouteFallback()} } /> @@ -118,7 +126,7 @@ export function AppRouter() { path="travel-requests" element={ - + {withRouteFallback()} } /> @@ -127,7 +135,7 @@ export function AppRouter() { path="assets" element={ - + {withRouteFallback()} } /> @@ -136,7 +144,7 @@ export function AppRouter() { path="inventory-checks" element={ - + {withRouteFallback()} } /> @@ -145,7 +153,7 @@ export function AppRouter() { path="workflow/tasks" element={ - + {withRouteFallback()} } /> @@ -154,7 +162,7 @@ export function AppRouter() { path="workflow/tasks/:taskId" element={ - + {withRouteFallback()} } /> @@ -163,7 +171,7 @@ export function AppRouter() { path="invoice-pool" element={ - + {withRouteFallback()} } /> @@ -172,7 +180,7 @@ export function AppRouter() { path="mobile/capture" element={ - + {withRouteFallback()} } /> @@ -181,7 +189,7 @@ export function AppRouter() { path="mobile/assets/scan" element={ - + {withRouteFallback()} } /> @@ -190,18 +198,18 @@ export function AppRouter() { path="mobile/approvals" element={ - + {withRouteFallback()} } /> - } /> + )} /> - + {withRouteFallback()} } /> @@ -210,7 +218,7 @@ export function AppRouter() { path="delegations" element={ - + {withRouteFallback()} } /> @@ -219,7 +227,7 @@ export function AppRouter() { path="system/users" element={ - + {withRouteFallback()} } /> @@ -228,7 +236,7 @@ export function AppRouter() { path="system/departments" element={ - + {withRouteFallback()} } /> @@ -237,7 +245,7 @@ export function AppRouter() { path="system/master-data" element={ - + {withRouteFallback()} } /> @@ -246,7 +254,7 @@ export function AppRouter() { path="system/notification-channels" element={ - + {withRouteFallback()} } /> @@ -255,7 +263,7 @@ export function AppRouter() { path="system/integrations/erp" element={ - + {withRouteFallback()} } /> @@ -264,7 +272,7 @@ export function AppRouter() { path="system/approval-rules" element={ - + {withRouteFallback()} } /> @@ -273,7 +281,7 @@ export function AppRouter() { path="system/feature-flags" element={ - + {withRouteFallback()} } /> diff --git a/client/src/router/lazy/ApprovalRulesPage.ts b/client/src/router/lazy/ApprovalRulesPage.ts new file mode 100644 index 00000000..6b1efb0e --- /dev/null +++ b/client/src/router/lazy/ApprovalRulesPage.ts @@ -0,0 +1 @@ +export { ApprovalRulesPage as default } from "../../pages/ApprovalRulesPage"; diff --git a/client/src/router/lazy/AssetRegistryPage.ts b/client/src/router/lazy/AssetRegistryPage.ts new file mode 100644 index 00000000..07d90d57 --- /dev/null +++ b/client/src/router/lazy/AssetRegistryPage.ts @@ -0,0 +1 @@ +export { AssetRegistryPage as default } from "../../pages/AssetRegistryPage"; diff --git a/client/src/router/lazy/AuditLogsPage.ts b/client/src/router/lazy/AuditLogsPage.ts new file mode 100644 index 00000000..d9b731e0 --- /dev/null +++ b/client/src/router/lazy/AuditLogsPage.ts @@ -0,0 +1 @@ +export { AuditLogsPage as default } from "../../pages/AuditLogsPage"; diff --git a/client/src/router/lazy/DelegationsPage.ts b/client/src/router/lazy/DelegationsPage.ts new file mode 100644 index 00000000..f4c9efa5 --- /dev/null +++ b/client/src/router/lazy/DelegationsPage.ts @@ -0,0 +1 @@ +export { DelegationsPage as default } from "../../pages/DelegationsPage"; diff --git a/client/src/router/lazy/DepartmentsPage.ts b/client/src/router/lazy/DepartmentsPage.ts new file mode 100644 index 00000000..2bbf3468 --- /dev/null +++ b/client/src/router/lazy/DepartmentsPage.ts @@ -0,0 +1 @@ +export { DepartmentsPage as default } from "../../pages/DepartmentsPage"; diff --git a/client/src/router/lazy/ErpIntegrationPage.ts b/client/src/router/lazy/ErpIntegrationPage.ts new file mode 100644 index 00000000..fb3891ce --- /dev/null +++ b/client/src/router/lazy/ErpIntegrationPage.ts @@ -0,0 +1 @@ +export { ErpIntegrationPage as default } from "../../pages/ErpIntegrationPage"; diff --git a/client/src/router/lazy/FeatureFlagsPage.ts b/client/src/router/lazy/FeatureFlagsPage.ts new file mode 100644 index 00000000..2b0ab4a9 --- /dev/null +++ b/client/src/router/lazy/FeatureFlagsPage.ts @@ -0,0 +1 @@ +export { FeatureFlagsPage as default } from "../../pages/FeatureFlagsPage"; diff --git a/client/src/router/lazy/InventoryChecksPage.ts b/client/src/router/lazy/InventoryChecksPage.ts new file mode 100644 index 00000000..0be2157f --- /dev/null +++ b/client/src/router/lazy/InventoryChecksPage.ts @@ -0,0 +1 @@ +export { InventoryChecksPage as default } from "../../pages/InventoryChecksPage"; diff --git a/client/src/router/lazy/InvoicePoolPage.ts b/client/src/router/lazy/InvoicePoolPage.ts new file mode 100644 index 00000000..ee8b0167 --- /dev/null +++ b/client/src/router/lazy/InvoicePoolPage.ts @@ -0,0 +1 @@ +export { InvoicePoolPage as default } from "../../pages/InvoicePoolPage"; diff --git a/client/src/router/lazy/LeaveRequestPage.ts b/client/src/router/lazy/LeaveRequestPage.ts new file mode 100644 index 00000000..975e6db1 --- /dev/null +++ b/client/src/router/lazy/LeaveRequestPage.ts @@ -0,0 +1 @@ +export { LeaveRequestPage as default } from "../../pages/LeaveRequestPage"; diff --git a/client/src/router/lazy/MasterDataPage.ts b/client/src/router/lazy/MasterDataPage.ts new file mode 100644 index 00000000..9d0f3d0d --- /dev/null +++ b/client/src/router/lazy/MasterDataPage.ts @@ -0,0 +1 @@ +export { MasterDataPage as default } from "../../pages/MasterDataPage"; diff --git a/client/src/router/lazy/MobileApprovalsPage.ts b/client/src/router/lazy/MobileApprovalsPage.ts new file mode 100644 index 00000000..bd70cf7f --- /dev/null +++ b/client/src/router/lazy/MobileApprovalsPage.ts @@ -0,0 +1 @@ +export { MobileApprovalsPage as default } from "../../pages/MobileApprovalsPage"; diff --git a/client/src/router/lazy/MobileAssetScanPage.ts b/client/src/router/lazy/MobileAssetScanPage.ts new file mode 100644 index 00000000..59bb81df --- /dev/null +++ b/client/src/router/lazy/MobileAssetScanPage.ts @@ -0,0 +1 @@ +export { MobileAssetScanPage as default } from "../../pages/MobileAssetScanPage"; diff --git a/client/src/router/lazy/MobileCapturePage.ts b/client/src/router/lazy/MobileCapturePage.ts new file mode 100644 index 00000000..c8cb1e20 --- /dev/null +++ b/client/src/router/lazy/MobileCapturePage.ts @@ -0,0 +1 @@ +export { MobileCapturePage as default } from "../../pages/MobileCapturePage"; diff --git a/client/src/router/lazy/NotificationChannelsPage.ts b/client/src/router/lazy/NotificationChannelsPage.ts new file mode 100644 index 00000000..fdf9c78d --- /dev/null +++ b/client/src/router/lazy/NotificationChannelsPage.ts @@ -0,0 +1 @@ +export { NotificationChannelsPage as default } from "../../pages/NotificationChannelsPage"; diff --git a/client/src/router/lazy/NotificationsPage.ts b/client/src/router/lazy/NotificationsPage.ts new file mode 100644 index 00000000..d1e0d67c --- /dev/null +++ b/client/src/router/lazy/NotificationsPage.ts @@ -0,0 +1 @@ +export { NotificationsPage as default } from "../../pages/NotificationsPage"; diff --git a/client/src/router/lazy/PurchaseRequestsPage.ts b/client/src/router/lazy/PurchaseRequestsPage.ts new file mode 100644 index 00000000..e691ff7f --- /dev/null +++ b/client/src/router/lazy/PurchaseRequestsPage.ts @@ -0,0 +1 @@ +export { PurchaseRequestsPage as default } from "../../pages/PurchaseRequestsPage"; diff --git a/client/src/router/lazy/ReimbursementDetailPage.ts b/client/src/router/lazy/ReimbursementDetailPage.ts new file mode 100644 index 00000000..1d58f440 --- /dev/null +++ b/client/src/router/lazy/ReimbursementDetailPage.ts @@ -0,0 +1 @@ +export { ReimbursementDetailPage as default } from "../../pages/ReimbursementDetailPage"; diff --git a/client/src/router/lazy/ReimbursementsPage.ts b/client/src/router/lazy/ReimbursementsPage.ts new file mode 100644 index 00000000..927692ba --- /dev/null +++ b/client/src/router/lazy/ReimbursementsPage.ts @@ -0,0 +1 @@ +export { ReimbursementsPage as default } from "../../pages/ReimbursementsPage"; diff --git a/client/src/router/lazy/TravelRequestsPage.ts b/client/src/router/lazy/TravelRequestsPage.ts new file mode 100644 index 00000000..b4f4ef88 --- /dev/null +++ b/client/src/router/lazy/TravelRequestsPage.ts @@ -0,0 +1 @@ +export { TravelRequestsPage as default } from "../../pages/TravelRequestsPage"; diff --git a/client/src/router/lazy/UserManagementPage.ts b/client/src/router/lazy/UserManagementPage.ts new file mode 100644 index 00000000..10d19259 --- /dev/null +++ b/client/src/router/lazy/UserManagementPage.ts @@ -0,0 +1 @@ +export { UserManagementPage as default } from "../../pages/UserManagementPage"; diff --git a/client/src/router/lazy/WorkflowTaskDetailPage.ts b/client/src/router/lazy/WorkflowTaskDetailPage.ts new file mode 100644 index 00000000..64934ae6 --- /dev/null +++ b/client/src/router/lazy/WorkflowTaskDetailPage.ts @@ -0,0 +1 @@ +export { WorkflowTaskDetailPage as default } from "../../pages/WorkflowTaskDetailPage"; diff --git a/client/src/router/lazy/WorkflowTasksPage.ts b/client/src/router/lazy/WorkflowTasksPage.ts new file mode 100644 index 00000000..68a222db --- /dev/null +++ b/client/src/router/lazy/WorkflowTasksPage.ts @@ -0,0 +1 @@ +export { WorkflowTasksPage as default } from "../../pages/WorkflowTasksPage"; diff --git a/client/src/router/lazy/index.ts b/client/src/router/lazy/index.ts new file mode 100644 index 00000000..658ff6e3 --- /dev/null +++ b/client/src/router/lazy/index.ts @@ -0,0 +1,25 @@ +import { lazy } from "react"; + +export const AuditLogsPage = lazy(() => import("./AuditLogsPage")); +export const ApprovalRulesPage = lazy(() => import("./ApprovalRulesPage")); +export const AssetRegistryPage = lazy(() => import("./AssetRegistryPage")); +export const DelegationsPage = lazy(() => import("./DelegationsPage")); +export const DepartmentsPage = lazy(() => import("./DepartmentsPage")); +export const ErpIntegrationPage = lazy(() => import("./ErpIntegrationPage")); +export const FeatureFlagsPage = lazy(() => import("./FeatureFlagsPage")); +export const InventoryChecksPage = lazy(() => import("./InventoryChecksPage")); +export const InvoicePoolPage = lazy(() => import("./InvoicePoolPage")); +export const LeaveRequestPage = lazy(() => import("./LeaveRequestPage")); +export const MasterDataPage = lazy(() => import("./MasterDataPage")); +export const MobileApprovalsPage = lazy(() => import("./MobileApprovalsPage")); +export const MobileAssetScanPage = lazy(() => import("./MobileAssetScanPage")); +export const MobileCapturePage = lazy(() => import("./MobileCapturePage")); +export const NotificationChannelsPage = lazy(() => import("./NotificationChannelsPage")); +export const NotificationsPage = lazy(() => import("./NotificationsPage")); +export const PurchaseRequestsPage = lazy(() => import("./PurchaseRequestsPage")); +export const ReimbursementDetailPage = lazy(() => import("./ReimbursementDetailPage")); +export const ReimbursementsPage = lazy(() => import("./ReimbursementsPage")); +export const TravelRequestsPage = lazy(() => import("./TravelRequestsPage")); +export const UserManagementPage = lazy(() => import("./UserManagementPage")); +export const WorkflowTaskDetailPage = lazy(() => import("./WorkflowTaskDetailPage")); +export const WorkflowTasksPage = lazy(() => import("./WorkflowTasksPage")); diff --git a/client/vite.config.ts b/client/vite.config.ts index 8fc716e8..f2382c1d 100644 --- a/client/vite.config.ts +++ b/client/vite.config.ts @@ -2,6 +2,86 @@ import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; import { VitePWA } from "vite-plugin-pwa"; +const PAGE_CHUNK_PATTERNS = { + "page-travel": ["TravelRequestsPage"], + "page-assets": ["AssetRegistryPage", "InventoryChecksPage"], + "page-procurement": ["PurchaseRequestsPage"], + "page-workflow": ["WorkflowTasksPage", "WorkflowTaskDetailPage"], + "page-system": [ + "AuditLogsPage", + "ApprovalRulesPage", + "DelegationsPage", + "DepartmentsPage", + "ErpIntegrationPage", + "FeatureFlagsPage", + "InvoicePoolPage", + "LeaveRequestPage", + "MasterDataPage", + "NotificationChannelsPage", + "NotificationsPage", + "ReimbursementDetailPage", + "ReimbursementsPage", + "UserManagementPage", + ], + "page-mobile": ["MobileCapturePage", "MobileAssetScanPage", "MobileApprovalsPage"], +} as const; + +function resolveManualChunk(id: string) { + if (id.includes("node_modules")) { + if (["react", "react-dom", "react-router-dom"].some((pkg) => id.includes(`/node_modules/${pkg}/`))) { + return "vendor-react"; + } + + if (id.includes("/node_modules/@tanstack/react-query/")) { + return "vendor-query"; + } + + if (id.includes("/node_modules/@zxing/browser/")) { + return "vendor-scan"; + } + + if ( + id.includes("/node_modules/@radix-ui/") || + id.includes("/node_modules/class-variance-authority/") || + id.includes("/node_modules/clsx/") || + id.includes("/node_modules/tailwind-merge/") || + id.includes("/node_modules/sonner/") + ) { + return "vendor-ui"; + } + + return undefined; + } + + if ( + id.includes("/src/api/http.ts") || + id.includes("/src/api/types.ts") || + id.includes("/src/api/errorMessages.ts") || + id.includes("/src/api/auth.ts") || + id.includes("/src/auth/") || + id.includes("/src/components/common/") || + id.includes("/src/hooks/") || + id.includes("/src/lib/") || + id.includes("/src/pwa.ts") + ) { + return "app-core"; + } + + if (id.includes("/src/api/masterData.ts") || id.includes("/src/components/ai/")) { + return "app-domain-shared"; + } + + for (const [chunkName, pageNames] of Object.entries(PAGE_CHUNK_PATTERNS)) { + for (const pageName of pageNames) { + if (id.includes(`/src/router/lazy/${pageName}.ts`)) { + return chunkName; + } + } + } + + return undefined; +} + export default defineConfig({ plugins: [ react(), @@ -89,6 +169,15 @@ export default defineConfig({ }, }), ], + build: { + rollupOptions: { + output: { + manualChunks(id) { + return resolveManualChunk(id); + }, + }, + }, + }, server: { proxy: { "/api": {