import { defineConfig, UserConfig } from "vite"; import vue from "@vitejs/plugin-vue"; import dotenv from "dotenv"; import { loadAppConfig } from "./vite.config.utils.mts"; import path from "path"; import { fileURLToPath } from 'url'; // Load environment variables dotenv.config(); const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); /** * Optimized Vite configuration for Vue 3 + vue-facing-decorator * with enhanced code splitting and lazy loading capabilities * * @author Matthew Raymer * @version 1.0.0 */ export async function createOptimizedBuildConfig(mode: string): Promise { const appConfig = await loadAppConfig(); const isCapacitor = mode === "capacitor"; const isElectron = mode === "electron"; const isNative = isCapacitor || isElectron; // Set platform - PWA is always enabled for web platforms process.env.VITE_PLATFORM = mode; return { base: "/", plugins: [vue()], server: { port: parseInt(process.env.VITE_PORT || "8080"), fs: { strict: false }, // CORS headers disabled to allow images from any domain // This means SharedArrayBuffer is unavailable, but absurd-sql // will automatically fall back to IndexedDB mode which still works }, build: { outDir: "dist", assetsDir: 'assets', chunkSizeWarningLimit: 1000, rollupOptions: { external: isNative ? ['@capacitor/app'] : [], output: { format: 'esm', generatedCode: { preset: 'es2015' }, // Enhanced manual chunks for better code splitting manualChunks: { // Vendor chunks for better caching 'vue-vendor': ['vue', 'vue-router', 'pinia'], 'ui-vendor': ['@fortawesome/fontawesome-svg-core', '@fortawesome/vue-fontawesome'], 'crypto-vendor': ['@ethersproject/wallet', '@ethersproject/hdnode', 'ethereum-cryptography'], 'sql-vendor': ['@jlongster/sql.js', 'absurd-sql', 'dexie'], 'qr-vendor': ['qrcode', 'jsqr', 'vue-qrcode-reader'], 'three-vendor': ['three', '@tweenjs/tween.js'], 'utils-vendor': ['luxon', 'ramda', 'zod', 'axios'], // Platform-specific chunks ...(isCapacitor && { 'capacitor-vendor': ['@capacitor/core', '@capacitor/app', '@capacitor/camera'] }), ...(isElectron && { 'electron-vendor': ['electron'] }) } } }, // Optimize chunk loading target: 'es2015', minify: 'terser', terserOptions: { compress: { drop_console: process.env.NODE_ENV === 'production', drop_debugger: true } } }, worker: { format: 'es', plugins: () => [] }, define: { 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), 'process.env.VITE_PLATFORM': JSON.stringify(mode), __dirname: JSON.stringify(process.cwd()), __IS_MOBILE__: JSON.stringify(isCapacitor), __IS_ELECTRON__: JSON.stringify(isElectron), __USE_QR_READER__: JSON.stringify(!isCapacitor), 'process.platform': JSON.stringify('browser'), 'process.version': JSON.stringify('v16.0.0'), 'process.env.NODE_DEBUG': JSON.stringify(false), 'global.process': JSON.stringify({ platform: 'browser', version: 'v16.0.0', env: { NODE_DEBUG: false } }) }, resolve: { alias: { '@': path.resolve(__dirname, 'src'), '@nostr/tools': path.resolve(__dirname, 'node_modules/@nostr/tools'), '@nostr/tools/nip06': path.resolve(__dirname, 'node_modules/@nostr/tools/nip06'), ...appConfig.aliasConfig, 'path': path.resolve(__dirname, './src/utils/node-modules/path.js'), 'fs': path.resolve(__dirname, './src/utils/node-modules/fs.js'), 'crypto': path.resolve(__dirname, './src/utils/node-modules/crypto.js'), 'dexie-export-import': path.resolve(__dirname, 'node_modules/dexie-export-import') } }, optimizeDeps: { include: [ '@nostr/tools', '@nostr/tools/nip06', 'vue', 'vue-router', 'pinia', 'vue-facing-decorator' ], exclude: isNative ? [ 'register-service-worker', 'workbox-window', 'web-push', 'serviceworker-webpack-plugin', 'vite-plugin-pwa', '@vite-pwa/vue' ] : [] }, // Enhanced performance optimizations esbuild: { target: 'es2015', supported: { 'bigint': true } } }; } export default defineConfig(async () => createOptimizedBuildConfig('web'));