import { defineConfig, loadEnv } from 'vite' import vue from '@vitejs/plugin-vue' import path, { resolve } from 'path' import { VitePWA } from 'vite-plugin-pwa' import { readFileSync } from 'fs' // https://vitejs.dev/config/ export default defineConfig(({ command, mode }) => { // 加载环境变量 const env = loadEnv(mode, process.cwd(), '') return { plugins: [ vue(), VitePWA({ registerType: 'autoUpdate', manifest: JSON.parse(readFileSync('./public/manifest.json', 'utf-8')), workbox: { // 增加文件大小限制以处理大文件 maximumFileSizeToCacheInBytes: 10 * 1024 * 1024, // 10MB // 自定义缓存策略 runtimeCaching: [ { urlPattern: /^https:\/\/fonts\.googleapis\.com\/.*/i, handler: 'CacheFirst', options: { cacheName: 'google-fonts-cache', expiration: { maxEntries: 10, maxAgeSeconds: 60 * 60 * 24 * 365 // <== 365 days } } }, { urlPattern: /^http:\/\/127\.0\.0\.1:8091\/.*/i, handler: 'NetworkFirst', options: { cacheName: 'api-cache', expiration: { maxEntries: 50, maxAgeSeconds: 60 * 60 * 24 // 24 hours } } } ] }, devOptions: { enabled: true // 开发环境也启用 PWA } }) ], resolve: { alias: { '@': path.resolve(__dirname, 'src'), }, extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'] }, server: { port: 3000, host: '0.0.0.0', open: true, proxy: { '/api': { target: 'http://127.0.0.1:8091', changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, '') }, // 添加日志以查看代理是否生效 onProxyReq(proxyReq, req, res) { console.log('代理请求:', req.method, req.url); }, onProxyRes(proxyRes, req, res) { console.log('代理响应:', proxyRes.statusCode, req.url); } }, fs: { strict: true, allow: ['..'] } }, optimizeDeps: { include: [ 'vue', 'vue-router', 'pinia', '@element-plus/icons-vue', 'element-plus' ] }, build: { // 生产环境禁用 sourcemap 以节省内存 sourcemap: mode === 'development', chunkSizeWarningLimit: 3000, // 启用压缩,减少输出文件大小 minify: 'terser', terserOptions: { compress: { // 移除 console 和 debugger drop_console: mode === 'production', drop_debugger: true } }, rollupOptions: { // 配置 Rollup 以处理大型项目 maxParallelFileOps: 2, // 限制并行文件操作数量 input: { main: resolve(__dirname, 'index.html'), // 为每个模块生成独立的HTML入口 dashboard: resolve(__dirname, 'public/dashboard.html'), crm: resolve(__dirname, 'public/crm.html'), org: resolve(__dirname, 'public/org.html'), task: resolve(__dirname, 'public/task.html'), knowledge: resolve(__dirname, 'public/knowledge.html'), email: resolve(__dirname, 'public/email.html'), manager: resolve(__dirname, 'public/manager.html') }, output: { // 确保文件名包含 hash,实现自动缓存失效 entryFileNames: 'assets/[name]-[hash].js', chunkFileNames: 'assets/[name]-[hash].js', assetFileNames: 'assets/[name]-[hash].[ext]', // 优化 chunk 分割策略 manualChunks: { // 框架相关 'vue-vendor': ['vue', 'vue-router', 'pinia'], // UI 组件库 'element-plus': ['element-plus', '@element-plus/icons-vue'], // 图表库 'echarts': ['echarts'], // 表格组件 'vxe-table': ['vxe-table'], // 编辑器相关 'editor': ['@umoteam/editor'], // 其他工具库 'utils': ['crypto-js', 'axios'] } }, // 外部化一些大型依赖(如果可能) external: [] } } } })