import { defineConfig, loadEnv } from 'vite' import vue from '@vitejs/plugin-vue' import path from 'path' import { fileURLToPath } from 'url' import vueDevTools from 'vite-plugin-vue-devtools' import viteCompression from 'vite-plugin-compression' import Components from 'unplugin-vue-components/vite' import AutoImport from 'unplugin-auto-import/vite' import ElementPlus from 'unplugin-element-plus/vite' import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' import tailwindcss from '@tailwindcss/vite' // @photo/admin:dev 固定 5176(CORS_ORIGINS 已包含);/v1 代理到本机 API(8080), // 仅作用于 `vite dev`——生产由网关同源挂载 /v1(同 apps/viewer 约定)。 // host 显式 127.0.0.1:Windows 下 localhost 默认可能只绑 [::1],代理/e2e 探活走 IPv4。 export default ({ mode }: { mode: string }) => { const root = process.cwd() const env = loadEnv(mode, root) // .env 不入库(仓库约定):缺省时给兜底值,保证全新 clone 可直接构建 const VITE_VERSION = env.VITE_VERSION || '0.1.0' const VITE_BASE_URL = env.VITE_BASE_URL || '/' console.log(`🚀 VERSION = ${VITE_VERSION}`) return defineConfig({ define: { __APP_VERSION__: JSON.stringify(VITE_VERSION) }, base: VITE_BASE_URL, server: { host: '127.0.0.1', port: 5176, strictPort: true, proxy: { '/v1': { target: 'http://127.0.0.1:8080', changeOrigin: true } } }, preview: { host: '127.0.0.1', port: 5176, strictPort: true }, // 路径别名 resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)), '@views': resolvePath('src/views'), '@imgs': resolvePath('src/assets/images'), '@icons': resolvePath('src/assets/icons'), '@utils': resolvePath('src/utils'), '@stores': resolvePath('src/store'), '@styles': resolvePath('src/assets/styles') } }, build: { target: 'es2015', outDir: 'dist', chunkSizeWarningLimit: 2000, minify: 'terser', terserOptions: { compress: { // 生产环境去除 console drop_console: true, // 生产环境去除 debugger drop_debugger: true } }, dynamicImportVarsOptions: { warnOnError: true, exclude: [], include: ['src/views/**/*.vue'] } }, plugins: [ vue(), tailwindcss(), // 自动按需导入 API AutoImport({ imports: ['vue', 'vue-router', 'pinia', '@vueuse/core'], dts: 'src/types/import/auto-imports.d.ts', resolvers: [ElementPlusResolver()], eslintrc: { enabled: true, filepath: './.auto-import.json', globalsPropValue: true } }), // 自动按需导入组件 Components({ dts: 'src/types/import/components.d.ts', resolvers: [ElementPlusResolver()] }), // 按需定制主题配置 ElementPlus({ useSource: true }), // 压缩 viteCompression({ verbose: false, // 是否在控制台输出压缩结果 disable: false, // 是否禁用 algorithm: 'gzip', // 压缩算法 ext: '.gz', // 压缩后的文件名后缀 threshold: 10240, // 只有大小大于该值的资源会被处理 10240B = 10KB deleteOriginFile: false // 压缩后是否删除原文件 }), vueDevTools() ], // 依赖预构建:避免运行时重复请求与转换,提升首次加载速度 // @photo/admin 裁剪:echarts/xlsx/xgplayer/file-saver/vue-img-cutter 等演示依赖已移除 optimizeDeps: { include: [ 'crypto-js', 'element-plus/es', 'element-plus/es/components/*/style/css', 'element-plus/es/components/*/style/index' ] }, css: { preprocessorOptions: { // sass variable and mixin scss: { additionalData: ` @use "@styles/core/el-light.scss" as *; @use "@styles/core/mixin.scss" as *; ` } }, postcss: { plugins: [ { postcssPlugin: 'internal:charset-removal', AtRule: { charset: (atRule) => { if (atRule.name === 'charset') { atRule.remove() } } } } ] } } }) } function resolvePath(paths: string) { return path.resolve(fileURLToPath(new URL('.', import.meta.url)), paths) }