1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
| import { fileURLToPath, URL } from 'node:url';
| import react from '@vitejs/plugin-react';
| import { defineConfig, loadEnv } from 'vite';
|
| /**
| * 布局、登录等入口页面会用到的 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,
| proxy: {
| '/proxy-api': {
| target: proxyTarget,
| changeOrigin: true,
| rewrite: (path) => path.replace(/^\/proxy-api/, ''),
| },
| },
| },
| build: {
| // 首屏 chunk 已控制在 600KB 以内;按需加载的 ProComponents 业务包约 830KB。
| chunkSizeWarningLimit: 900,
| rollupOptions: {
| output: {
| manualChunks: resolveVendorChunk,
| },
| },
| },
| };
| });
|
|