import { fileURLToPath, URL } from 'node:url' import { defineConfig, loadEnv } from 'vite' import vue from '@vitejs/plugin-vue' import AutoImport from 'unplugin-auto-import/vite' import Components from 'unplugin-vue-components/vite' import DefineOptions from 'unplugin-vue-define-options/vite' import { createSvgIconsPlugin } from 'vite-plugin-svg-icons' import path from 'path' import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers' // console.log(process) // console.log(import.meta.env.VITE_APP_URL) // https://vitejs.dev/config/ export default defineConfig(({ mode }) => { const env = loadEnv(mode, process.cwd()) const isProduction = mode === 'production' return { plugins: [ vue(), DefineOptions(), AutoImport({ resolvers: [], imports: [ 'vue', 'vue-router', { 'lodash-es': [ 'debounce', 'cloneDeep', 'cloneDeepWith', 'isBoolean', 'isString', 'isNumber', 'isArray', 'isDate', 'isFunction', 'isNaN', 'isNull', 'isObject', 'isUndefined' ] } ] }), Components({ resolvers: [AntDesignVueResolver({ importStyle: false })] }), createSvgIconsPlugin({ iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')], symbolId: 'icon-[dir]-[name]', inject: 'body-last' }) ], define: { __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: false }, css: { preprocessorOptions: { less: { modifyVars: { 'primary-color': '#ec6800' }, javascriptEnabled: true, additionalData: `@import "${path.resolve(__dirname, 'src/assets/css/style.less')}";` } } }, resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)), _c: fileURLToPath(new URL('./src/components', import.meta.url)) } }, server: { host: '0.0.0.0', port: 8088, open: true, strictPort: true, hmr: { overlay: true }, proxy: { '/api': { target: env.VITE_APP_URL, changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, '/api') } } }, // ========== 打包配置 ========== build: { // 构建目标浏览器 target: 'es2015', // 是否生成 sourcemap sourcemap: isProduction ? false : 'eval', // 打包文件输出目录 outDir: 'dist', // 静态资源输出目录(相对于 outDir) assetsDir: 'assets', // 小于此阈值的导入将内联为 base64 assetsInlineLimit: 4096, // 启用 CSS 代码分割 cssCodeSplit: true, // 公共基础路径 publicDir: 'public', // 启用 gzip 压缩大小限制 chunkSizeWarningLimit: 500, // 自定义 chunk 分包策略 rollupOptions: { output: { // 静态资源打包命名 assetFileNames: (assetInfo) => { const info = assetInfo.name || '' if (/\.(woff|woff2?|eot|ttf|otf)$/i.test(info)) { return 'assets/fonts/[name]-[hash][extname]' } if (/\.(png|jpe?g|gif|svg|webp|avif|ico)$/i.test(info)) { return 'assets/images/[name]-[hash][extname]' } if (/\.(mp4|webm|ogg|mp3|wav|flac|aac)$/i.test(info)) { return 'assets/media/[name]-[hash][extname]' } return 'assets/[name]-[hash][extname]' }, // chunk 分包命名 chunkFileNames: 'assets/js/[name]-[hash].js', // 入口文件命名 entryFileNames: 'assets/js/[name]-[hash].js', // 手动分包策略 manualChunks: { // 核心框架 'vue-core': ['vue', 'vue-router', 'pinia', 'pinia-plugin-persistedstate'], // 国际化 'vue-i18n-core': ['vue-i18n'], // UI 框架 'ant-design': ['ant-design-vue'], // 工具库 'utils': ['lodash-es', 'axios'], // 其他依赖 'vendor': ['gsap', 'crypto-js'] } } }, // 依赖预构建优化 optimizeDeps: { include: [ 'vue', 'vue-router', 'pinia', 'vue-i18n', 'ant-design-vue', 'axios', 'lodash-es', 'gsap', 'crypto-js' ] }, // 压缩配置 minify: 'terser', terserOptions: { compress: { drop_console: isProduction, // 生产环境移除 console drop_debugger: isProduction, // 生产环境移除 debugger pure_funcs: isProduction ? ['console.log'] : [] }, format: { comments: false // 移除注释 } } }, // 预览服务器配置 preview: { host: '0.0.0.0', port: 8088, open: true, proxy: { '/api': { target: env.VITE_APP_URL, changeOrigin: true } } } } })