/** * Vite 优化配置 * * 这是一个优化后的 vite 配置文件,包含: * - 更细粒度的 chunk 拆分 * - Bundle 分析工具 * - 图片压缩 * * 使用方法: * 1. 备份当前的 vite.config.ts * 2. 将此文件重命名为 vite.config.ts * 3. 安装必要依赖: npm install --save-dev rollup-plugin-visualizer */ import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import { visualizer } from 'rollup-plugin-visualizer'; // https://vite.dev/config/ export default defineConfig({ plugins: [ react(), // Bundle 分析工具(仅在需要时启用) // 运行 npm run build 后会生成 dist/stats.html process.env.ANALYZE === 'true' && visualizer({ open: true, filename: 'dist/stats.html', gzipSize: true, brotliSize: true, template: 'treemap', // 'sunburst' | 'treemap' | 'network' }), ].filter(Boolean), build: { // 使用 Vite 8 默认的 oxc 压缩器(最快) // 如果需要更高压缩率,可以改为 'esbuild' 或 'terser' // minify: 'esbuild', // 提高 chunk 大小警告阈值(Ant Design 较大) chunkSizeWarningLimit: 600, rollupOptions: { output: { /** * 优化的手动 chunk 拆分策略 * * 目标: * 1. 将不同功能的库拆分到独立 chunk * 2. 提高浏览器缓存命中率 * 3. 减少首次加载体积 */ manualChunks(id: string) { // ========== 核心框架 ========== if (id.includes('node_modules/react') || id.includes('node_modules/react-dom')) { return 'react-vendor'; } // ========== UI 组件库 ========== // Ant Design 核心组件(高频使用) if ( id.includes('node_modules/antd/es/button') || id.includes('node_modules/antd/es/input') || id.includes('node_modules/antd/es/form') || id.includes('node_modules/antd/es/space') || id.includes('node_modules/antd/es/card') || id.includes('node_modules/antd/es/spin') ) { return 'antd-core'; } // Ant Design 扩展组件(低频使用) if ( id.includes('node_modules/antd/es/table') || id.includes('node_modules/antd/es/drawer') || id.includes('node_modules/antd/es/modal') || id.includes('node_modules/antd/es/dropdown') || id.includes('node_modules/antd/es/menu') ) { return 'antd-extended'; } // 其他 Ant Design 代码和图标 if (id.includes('node_modules/antd') || id.includes('node_modules/@ant-design')) { return 'antd-vendor'; } // ========== 文档处理库(按需加载)========== // Word 文档解析(mammoth, docx-preview) if ( id.includes('node_modules/mammoth') || id.includes('node_modules/docx-preview') ) { return 'document-libs-vendor'; } // ========== 导出功能库(按需加载)========== // PDF 和截图(jspdf, html2canvas) if ( id.includes('node_modules/jspdf') || id.includes('node_modules/html2canvas') ) { return 'export-libs-vendor'; } // HTML 转 Markdown(turndown) if (id.includes('node_modules/turndown')) { return 'markdown-converter-vendor'; } // ========== Markdown 渲染库 ========== // react-markdown 及其依赖 if ( id.includes('node_modules/react-markdown') || id.includes('node_modules/remark-') || id.includes('node_modules/rehype-') || id.includes('node_modules/unified') || id.includes('node_modules/micromark') ) { return 'markdown-vendor'; } // ========== 编辑器相关 ========== // Slate.js 富文本编辑器(如果使用) if ( id.includes('node_modules/slate') || id.includes('node_modules/slate-react') || id.includes('node_modules/slate-history') ) { return 'slate-vendor'; } // ========== 工具库 ========== // HTTP 客户端 if (id.includes('node_modules/axios')) { return 'axios-vendor'; } // 状态管理 if (id.includes('node_modules/zustand')) { return 'zustand-vendor'; } // 其他小型工具库 if ( id.includes('node_modules/uuid') || id.includes('node_modules/dayjs') || id.includes('node_modules/lodash') ) { return 'utils-vendor'; } // ========== 其他第三方库 ========== if (id.includes('node_modules')) { return 'vendor'; } // 应用代码(由 React.lazy 自动分割) // 不需要在这里处理 }, }, // Tree-shaking 配置(移除未使用的代码) treeshake: { moduleSideEffects: false, propertyReadSideEffects: false, }, }, // 启用 CSS 代码分割 cssCodeSplit: true, // 启用源码映射(方便调试,生产环境可关闭) sourcemap: process.env.NODE_ENV !== 'production', // 产物输出目录 outDir: 'dist', // 静态资源处理 assetsDir: 'assets', // 小于此阈值的资源将内联为 base64 assetsInlineLimit: 4096, // 4KB }, // 开发服务器配置 server: { port: 5173, host: true, // 监听所有地址 open: false, // 不自动打开浏览器 // 预加载优化 warmup: { clientFiles: [ './src/App.tsx', './src/components/ChatPanel/ChatPanel.tsx', './src/components/EditorPanel/EditorPanel.tsx', ], }, }, // 依赖预构建优化 optimizeDeps: { include: [ 'react', 'react-dom', 'axios', 'zustand', 'antd', '@ant-design/icons', ], // 排除不需要预构建的大型依赖 exclude: [ 'mammoth', 'docx-preview', 'jspdf', 'html2canvas', ], }, });