import { defineConfig } from 'vite' import uni from '@dcloudio/vite-plugin-uni' import { resolve } from 'path' import { readFileSync, writeFileSync, existsSync, unlinkSync } from 'fs' import dotenv from 'dotenv' // 自定义插件:替换 manifest.json 中的 appid // 仅在通过HBuilder首次编译时执行,避免热重载时重复执行导致内存占用高 function replaceManifestAppid() { return { name: 'replace-manifest-appid', buildStart() { // 检查是否通过HBuilder编译 // 检查是否已经执行过插件 const manifestUpdatedFlag = resolve(__dirname, '.manifest-updated') const isFirstCompile = !existsSync(manifestUpdatedFlag) // 仅首次编译时执行 if (!isFirstCompile) { console.log('跳过 manifest appid 更新(已执行过首次编译)') return } // 获取环境变量,明确指定路径为项目根目录 dotenv.config({ path: resolve(__dirname, '.env') }) const appid = process.env.VITE_APPID const uni_appId = process.env.VITE_UNI_APPID if (appid && uni_appId) { // 读取 manifest.json 文件 const manifestPath = resolve(__dirname, 'manifest.json') let manifestContent = readFileSync(manifestPath, 'utf-8') // 解析 JSON const manifest = JSON.parse(manifestContent) // 替换 manifest.appid = uni_appId if (manifest['mp-weixin']) { manifest['mp-weixin'].appid = appid } // 写回文件 writeFileSync(manifestPath, JSON.stringify(manifest, null, 4)) // 创建标记文件,表示已执行过插件 writeFileSync(manifestUpdatedFlag, 'Manifest updated by HBuilder first compile') console.log(`Manifest appid 已更新为: ${uni_appId}`) console.log(`Manifest mp-weixin appid 已更新为: ${appid}`) } else { console.warn('未找到 VITE_APPID 和 VITE_UNI_APPID 环境变量,使用默认值') } }, } } // 检查是否通过HBuilder编译,决定是否启用插件 const manifestUpdatedFlag = resolve(__dirname, '.manifest-updated') if (existsSync(manifestUpdatedFlag)) { unlinkSync(manifestUpdatedFlag) console.log('已清理 manifest 更新标记文件') } const plugins = manifestUpdatedFlag ? [replaceManifestAppid(), uni()] : [uni()] export default defineConfig({ plugins, resolve: { alias: { '@': resolve(__dirname, 'src'), }, }, build: { minify: 'terser', terserOptions: { compress: { drop_console: true, drop_debugger: true, pure_funcs: ['console.log'], // 移除console.log }, }, rollupOptions: { output: { // 静态资源分类打包 assetFileNames: (assetInfo) => { let extType = assetInfo.name.split('.').at(1) if (/png|jpe?g|svg|gif|tiff|bmp|ico/i.test(extType)) { extType = 'img' } else if (/woff|woff2|eot|ttf|otf/i.test(extType)) { extType = 'font' } return `static/${extType}/[name]-[hash].[ext]` }, // 分包 chunkFileNames: 'static/js/[name]-[hash].js', entryFileNames: 'static/js/[name]-[hash].js', manualChunks: { // 将第三方库单独打包 vue: ['vue'], 'uview-plus': ['uview-plus'], 'luch-request': ['luch-request'], }, }, }, // 启用 CSS 代码分割 cssCodeSplit: true, // 小于此阈值的导入或引用资源将内联为 base64 编码 assetsInlineLimit: 4096, // 启用 gzip 压缩 brotliSize: true, }, // 优化选项 optimizeDeps: { include: ['vue', 'uview-plus', 'luch-request'], }, // 开发服务器配置 server: { host: '0.0.0.0', port: 3000, open: true, // 代理配置 proxy: { '/api': { target: process.env.VITE_BASE_URL, changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, ''), }, }, }, })