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}${tag}>` 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 = `\n${content}`
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,
})
},
},
],
})