import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import vueJsx from '@vitejs/plugin-vue-jsx' import { federation } from '@module-federation/vite' import { resolve, dirname } from 'path' import { fileURLToPath } from 'url' import fs from 'fs' const __filename = fileURLToPath(import.meta.url) const __dirname = dirname(__filename) /** * Module Federation 构建配置(@module-federation/vite) * 官方维护版本,支持 Vite 6 + 开发模式热更新 * * 优势: * - ✅ 完整支持 Vite 开发模式 * - ✅ dev 模式能生成 remoteEntry.js * - ✅ 自动处理内部路径别名 (@/) * - ✅ 真正的生产可用版本 */ export default defineConfig({ // Shared 模块的基础路径(通过 Nginx 代理访问) base: '/shared/', plugins: [ vue({ script: { defineModel: true, propsDestructure: true } }), vueJsx(), federation({ name: 'shared', filename: 'remoteEntry.js', // 暴露的模块 exposes: { // ========== 组件模块 ========== './components': './src/components/index.ts', './components/file/FileUpload': './src/components/file/fileupload/FileUpload.vue', './components/file/FileHistory': './src/components/file/fileHistory/FileHistory.vue', './components/DynamicFormItem': './src/components/dynamicFormItem/DynamicFormItem.vue', './components/iframe/IframeView.vue': './src/components/iframe/IframeView.vue', './components/ai/knowledge/DocumentSegment.vue': './src/components/ai/knowledge/documentSegment/DocumentSegment.vue', './components/ai/knowledge/DocumentDetail.vue': './src/components/ai/knowledge/documentDetail/DocumentDetail.vue', // ========== API 模块 ========== './api': './src/api/index.ts', './api/auth': './src/api/auth/auth.ts', './api/file': './src/api/file/file.ts', './api/ai': './src/api/ai/index.ts', // ========== Utils 工具模块 ========== './utils': './src/utils/index.ts', './utils/device': './src/utils/device.ts', './utils/route': './src/utils/route/index.ts', './utils/route/generator': './src/utils/route/route-generator.ts', './utils/file': './src/utils/file.ts', // ========== Types 类型模块 ========== './types': './src/types/index.ts', './types/base': './src/types/base/index.ts', './types/auth': './src/types/auth/index.ts', './types/file': './src/types/file/index.ts', './types/sys': './src/types/sys/index.ts', './types/ai': './src/types/ai/index.ts', // ========== Config 配置模块 ========== './config': './src/config/index.ts', // ========== Layouts 布局模块 ========== './layouts': './src/layouts/index.ts', // ========== Styles 样式模块 ========== // 直接暴露 SCSS 文件,确保 CSS 在远程加载时被正确注入 './styles': './src/styles/index.scss' }, // 共享依赖(重要:避免重复加载) shared: { vue: {}, 'vue-router': {}, 'element-plus': {}, 'lucide-vue-next': {}, axios: {} } }) ], define: { __VUE_OPTIONS_API__: true, __VUE_PROD_DEVTOOLS__: true, __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: true }, resolve: { alias: { '@': resolve(__dirname, 'src') }, extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'] }, build: { target: 'esnext', minify: false, cssCodeSplit: false, sourcemap: true, // 确保 CSS 被提取到单独的文件中 cssMinify: true, rollupOptions: { output: { format: 'es', // 确保 CSS 文件名可预测 assetFileNames: (assetInfo) => { if (assetInfo.name === 'style.css') { return 'assets/style.css' } return 'assets/[name]-[hash][extname]' } } } }, server: { port: 7000, strictPort: true, host: true, cors: true, // HTTPS 配置(本地开发用,可选) https: (() => { try { return { key: fs.readFileSync('C:/Users/FK05/443/localhost+3-key.pem'), cert: fs.readFileSync('C:/Users/FK05/443/localhost+3.pem') } } catch { return undefined } })(), headers: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization' } }, preview: { port: 7000, host: true, cors: true, https: (() => { try { return { key: fs.readFileSync('C:/Users/FK05/443/localhost+3-key.pem'), cert: fs.readFileSync('C:/Users/FK05/443/localhost+3.pem') } } catch { return undefined } })(), headers: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization' } } })