| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- /**
- * 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',
- ],
- },
- });
|