From d26274d89d377067c1e2648192cffbf89464b361 Mon Sep 17 00:00:00 2001
From: wsj <593216709@qq.com>
Date: Wed, 28 Oct 2026 23:34:32 +0800
Subject: [PATCH] feat: 拆包

---
 vite.config.ts |  110 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 99 insertions(+), 11 deletions(-)

diff --git a/vite.config.ts b/vite.config.ts
index b76ce5c..5c245e3 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,16 +1,104 @@
 import { fileURLToPath, URL } from 'node:url';
 import react from '@vitejs/plugin-react';
-import { defineConfig } from 'vite';
+import { defineConfig, loadEnv } from 'vite';
 
-export default defineConfig({
-  plugins: [react()],
-  resolve: {
-    alias: {
-      '@': fileURLToPath(new URL('./src', import.meta.url)),
+/**
+ * 布局、登录等入口页面会用到的 antd 组件。
+ * 这些模块首屏必载,单独放进 antd chunk 以稳定缓存;
+ * 表格、日期选择等只在业务页面使用的组件则交给 Rollup 按需分包。
+ *
+ * 注意:不要匹配 `antd/es/index.js`(`from 'antd'` 的 barrel 文件)。
+ * manualChunks 会把 chunk 当成入口保留全部导出,barrel 进手动 chunk 后
+ * 会把所有 antd 组件都拉进首屏(约 1.3MB),失去按需分包的意义。
+ */
+const ANTD_CORE_DIRS = [
+  '_util',
+  'app',
+  'avatar',
+  'breadcrumb',
+  'button',
+  'config-provider',
+  'dropdown',
+  'form',
+  'input',
+  'layout',
+  'locale',
+  'menu',
+  'message',
+  'modal',
+  'notification',
+  'space',
+  'spin',
+  'style',
+  'tag',
+  'theme',
+  'tooltip',
+  'version',
+  'wave',
+].join('|');
+
+/** 第三方依赖拆包规则,页面本身通过路由懒加载按需加载。 */
+const resolveVendorChunk = (id: string): string | undefined => {
+  if (!id.includes('node_modules')) return undefined;
+
+  const path = id.replace(/\\/g, '/');
+
+  // 图标与 antd 互相引用,放在同一个 chunk,避免循环依赖。
+  if (
+    new RegExp(
+      `\\/node_modules\\/(antd\\/es\\/(${ANTD_CORE_DIRS})\\/|@ant-design\\/(cssinjs|cssinjs-utils|colors|fast-color|icons|icons-svg)\\/)`,
+    ).test(path)
+  ) {
+    return 'antd';
+  }
+
+  if (
+    /\/node_modules\/(react|react-dom|scheduler|react-router|react-router-dom|@remix-run\/[^/]+)\//.test(
+      path,
+    )
+  ) {
+    return 'react';
+  }
+
+  if (/\/node_modules\/(axios|zustand|dayjs)\//.test(path)) {
+    return 'vendor';
+  }
+
+  return undefined;
+};
+
+/** 开发环境通过 Vite 代理访问后端,避免浏览器跨域。 */
+export default defineConfig(({ mode }) => {
+  const env = loadEnv(mode, process.cwd(), '');
+  const proxyTarget =
+    env.VITE_API_PROXY_TARGET || env.VITE_API_BASE_URL || 'http://localhost:9090';
+
+  return {
+    plugins: [react()],
+    resolve: {
+      alias: {
+        '@': fileURLToPath(new URL('./src', import.meta.url)),
+      },
     },
-  },
-  server: {
-    port: 5173,
-    host: true,
-  },
+    server: {
+      port: 5173,
+      host: true,
+      proxy: {
+        '/proxy-api': {
+          target: proxyTarget,
+          changeOrigin: true,
+          rewrite: (path) => path.replace(/^\/proxy-api/, ''),
+        },
+      },
+    },
+    build: {
+      // 首屏 chunk 已控制在 600KB 以内;按需加载的 ProComponents 业务包约 830KB。
+      chunkSizeWarningLimit: 900,
+      rollupOptions: {
+        output: {
+          manualChunks: resolveVendorChunk,
+        },
+      },
+    },
+  };
 });

--
Gitblit v1.9.3