import { defineConfig, type Plugin, type UserConfig } from 'vite' import react from '@vitejs/plugin-react' import tsconfigPaths from 'vite-tsconfig-paths' import { VitePWA } from 'vite-plugin-pwa'; import * as path from 'path' // ✅ Import path module import { readFileSync, renameSync, existsSync, unlinkSync } from 'node:fs' import { fileURLToPath } from 'node:url' const rootDir = path.dirname(fileURLToPath(import.meta.url)) const NO_CRISP_MODE = 'nocrisp' function useNoCrispIndexHtml (mode: string, command: string): Plugin { if (mode !== NO_CRISP_MODE || command !== 'serve') { return { name: 'use-local-index-html-noop' } } return { name: 'use-local-index-html', apply: 'serve', transformIndexHtml: { order: 'pre', handler () { return readFileSync(path.join(rootDir, 'indexLocal.html'), 'utf-8') }, }, } } function emitNoCrispIndexAsIndexHtml (mode: string): Plugin { if (mode !== NO_CRISP_MODE) { return { name: 'emit-nocrisp-index-as-index-noop' } } return { name: 'emit-nocrisp-index-as-index-html', closeBundle () { const outDir = path.join(rootDir, 'build') const from = path.join(outDir, 'indexLocal.html') const to = path.join(outDir, 'index.html') if (existsSync(from)) { if (existsSync(to)) unlinkSync(to) renameSync(from, to) } }, } } // https://vitejs.dev/config/ export default defineConfig(({ command, mode }): UserConfig => { const useNoCrispIndex = mode === NO_CRISP_MODE return { plugins: [ useNoCrispIndexHtml(mode, command), emitNoCrispIndexAsIndexHtml(mode), react(), tsconfigPaths(), VitePWA({ registerType: 'autoUpdate', // Automatically updates the service worker when a new version is available workbox: { skipWaiting: true, //makes the new worker call skip waiting clientsClaim: true, //makes it claim control of clients as soon as it activates globPatterns: ['**/*.{js,css,html,png,jpg,svg}'], // Cache all common asset types maximumFileSizeToCacheInBytes: 20 * 1024 * 1024, // 20 MiB cleanupOutdatedCaches: true, navigateFallback: "/index.html", runtimeCaching: [ { urlPattern: ({ request }) => request.destination === 'document', handler: 'NetworkFirst', options: { cacheName: 'html-cache', }, }, { urlPattern: ({ request }) => ['style', 'script', 'worker'].includes(request.destination), handler: 'StaleWhileRevalidate', options: { cacheName: 'assets-cache', }, }, { //this forces all api calls to go through the network urlPattern: ({ url }) => url.pathname.startsWith('/v1/'), handler: 'NetworkOnly', options: { cacheName: 'api-cache', }, }, ] }, }), ], build: { outDir: './build', sourcemap: true, minify: false, target: 'esnext', rollupOptions: { input: { main: path.join( rootDir, useNoCrispIndex ? 'indexLocal.html' : 'index.html' ), }, } }, esbuild: { keepNames: true, // Prevent function name mangling }, } })