import { fileURLToPath, URL } from 'node:url' import { defineConfig, loadEnv } from 'vite' import vue from '@vitejs/plugin-vue' import vueJsx from '@vitejs/plugin-vue-jsx' import UnoCSS from 'unocss/vite' import { createSvgIconsPlugin } from 'vite-plugin-svg-icons' import VueRouter from 'unplugin-vue-router/vite' import Layouts from 'vite-plugin-vue-layouts' import AutoImport from 'unplugin-auto-import/vite' import { VueRouterAutoImports } from 'unplugin-vue-router' import Components from 'unplugin-vue-components/vite' import vueI18n from '@intlify/unplugin-vue-i18n/vite' import path from 'node:path' import { compression } from 'vite-plugin-compression2' import { ViteImageOptimizer } from 'vite-plugin-image-optimizer' import legacy from '@vitejs/plugin-legacy' import { visualizer } from 'rollup-plugin-visualizer' import vueDevTools from 'vite-plugin-vue-devtools' // https://vite.dev/config/ export default defineConfig(({ mode }) => { const env = loadEnv(mode, process.cwd(), 'VITE_') // 如果你有其他场景判断,可修改此处,本文假设只针对生产环境 const isProd = mode === 'prod' return { build: { outDir: 'dist', assetsDir: 'assets', assetsInlineLimit: 4096, reportCompressedSize: true, minify: 'terser', cssCodeSplit: true, sourcemap: !isProd, terserOptions: isProd ? { // 代码压缩配置 compress: { drop_console: true, // 移除 console drop_debugger: true, // 移除 debugger }, // 代码混淆配置 mangle: { toplevel: true, // 混淆顶层变量名 eval: true, // 混淆 eval 中的变量 }, // 输出配置 format: { comments: false, }, } : {}, olldownOptions: { output: { codeSplitting: { groups: [ { name: 'vue', test: /node_modules[\\/]vue/, priority: 20, }, { name: 'vue-router', test: /node_modules[\\/]vue-router/, priority: 15, }, { name: 'pinia', test: /node_modules[\\/]pinia/, priority: 10, }, ], }, }, }, }, plugins: [ VueRouter({}), // ⚠️ Vue must be placed after VueRouter() vue(), vueJsx(), UnoCSS(), // 配置 SVG 图标插件 createSvgIconsPlugin({ // SVG 图标目录 iconDirs: [fileURLToPath(new URL('./src/assets/icons', import.meta.url))], // 生成的 symbol ID 格式 symbolId: 'icon-[dir]-[name]', }), Layouts({ layoutsDirs: 'src/layouts', defaultLayout: 'default', }), AutoImport({ include: [ /\.[tj]sx?$/, // .ts, .tsx, .js, .jsx /\.vue$/, /\.vue\?vue/, // .vue /\.md$/, // .md ], imports: ['vue', VueRouterAutoImports, 'pinia', '@vueuse/core'], }), Components({ deep: true, directoryAsNamespace: false, }), vueI18n({ // 语言包目录 include: path.resolve(__dirname, './src/i18n/locales/**'), // 开发模式下也启动编译时处理 runtimeOnly: false, // 仅使用组合式 API compositionOnly: true, // 完整安装 fullInstall: true, }), // Gzip 压缩 compression({ algorithms: ['gzip'], threshold: 10240, // 超过 10KB 的文件才压缩 deleteOriginalAssets: false, // 不删除原文件 }), ViteImageOptimizer({ png: { quality: 80, }, jpeg: { quality: 80, }, webp: { quality: 80, }, }), legacy({ targets: ['defaults', 'not IE 11'], }), visualizer({ filename: 'stats.html', }), vueDevTools(), ], resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)), }, }, optimizeDeps: { include: ['vue', 'vue-router', 'pinia', '@vueuse/core'], }, } })