import { defineConfig } from 'vite' import { readFileSync } from 'fs' import { basename } from 'path' import { transpile } from 'typescript' import { minify } from 'html-minifier-next' import preact from '@preact/preset-vite' const appConfig = JSON.parse(readFileSync('tsconfig.app.json', 'utf8')) export default defineConfig({ build: { assetsInlineLimit: 999_999_999, cssMinify: 'esbuild', minify: 'esbuild', outDir: 'dist', rollupOptions: { input: { index: 'index.html', embed: 'embed.html', }, output: { hashCharacters: 'hex', entryFileNames: 'assets/[name].[hash].js', chunkFileNames: 'assets/[name].[hash].js', assetFileNames: 'assets/[name].[hash][extname]', }, }, }, server: { strictPort: true, port: 5173, proxy: { '/api': { // cd backend && go run main.go target: 'http://localhost:8080', changeOrigin: true, rewrite: (path) => path.replace('/api', ''), }, '/cdn': { // npx serve -C ./backend/_public target: 'http://localhost:3000', changeOrigin: true, rewrite: (path) => path.replace('/cdn', ''), }, }, }, plugins: [ preact(), { name: 'html-template', transformIndexHtml(html, ctx) { return html .replaceAll(/{{ include-env }}/g, () => { return `` }) .replaceAll(/{{ include-b64 '(.*?)' '(.*?)' }}/g, (_, mime: string, filepath: string) => { const content = readFileSync(filepath, 'base64') const inlined = `data:${mime};base64,${content}` this.warn(`Embedding 'base64' from '${filepath}'`) return inlined }) .replaceAll(/{{ include-tag '(.*?)' '(.*?)' }}/g, (_, tag: string, filepath: string) => { let content = readFileSync(filepath, 'utf8') if (tag === 'script' && filepath.endsWith('.ts')) { content = transpile(content, appConfig) this.warn(`Transpiled inline script : ${basename(filepath)}`) } const inlined = `<${tag}>\n${content}` this.warn(`Embedding '${tag}' from '${filepath}'`) return inlined }) .replaceAll(/{{ include-article '(.*?)' '(.*?)' }}/g, (_, id: string, filepath: string) => { const content = readFileSync(filepath, 'utf8').replaceAll( /]*)>\s*\n([\s\S]*?)<\/pre>/g, (_, attributes, inner) => { const lines = inner.split('\n') const indent = lines[0].match(/^(\s*)/)?.[1].length ?? 0 const trimmed = lines .map((l: string) => l.slice(indent)) .join('\n') .trim() return `${trimmed}` }, ) const inlined = `` this.warn(`Embedding article '${id}' from '${filepath}'`) return inlined }) }, }, { name: 'html-minify', transformIndexHtml(html, ctx) { if (ctx.server) return html // skip dev mode this.warn(`Minifying Document: ${basename(ctx.filename)}`) return minify(html, { collapseWhitespace: true, removeComments: true, minifyCSS: true, minifyJS: true, }) }, }, ], })