frontend/vite.config.ts

111 lines
3.3 KiB
TypeScript

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
},
}
})