import { defineConfig } from 'vite' import { readFileSync } from 'fs' import { basename, extname, join } from 'path' import { minify } from 'html-minifier-next' import { buildSync } from 'esbuild' const ROOT = join(process.cwd(), 'application') const DIST = join(ROOT, 'dist') export default defineConfig({ root: ROOT, build: { outDir: DIST, modulePreload: { polyfill: false, }, rollupOptions: { input: [ join(ROOT, 'index.html'), join(ROOT, 'not-found.html'), join(ROOT, 'qr-code.html'), join(ROOT, 'secret-sprites.html'), join(ROOT, 'secret-picross.html'), join(ROOT, 'about.html'), ], output: { hashCharacters: 'hex', entryFileNames: 'assets/[name].[hash].js', chunkFileNames: 'assets/[name].[hash].js', assetFileNames: 'assets/[name].[hash][extname]', }, }, }, server: { strictPort: true, port: 5173, }, plugins: [ { name: 'server-uri', configureServer(server) { const includeDir = join(ROOT, 'include') server.watcher.add(includeDir) server.watcher.on('change', (file) => { if (file.startsWith(includeDir)) { server.ws.send({ type: 'full-reload' }) } }) }, }, { name: 'html-generator', transformIndexHtml(html, _) { html = html.replaceAll(/{{ include-b64 '(.*?)' '(.*?)' }}/g, (_, mime: string, filepath: string) => { const content = readFileSync(join(ROOT, filepath), 'base64') return `data:${mime};base64,${content}` }) html = html.replaceAll(/{{ include-tag '(.*?)' '(.*?)' }}/g, (_, tag: string, filepath: string) => { if (tag === 'script' && filepath.endsWith('.ts')) { const result = buildSync({ entryPoints: [join(ROOT, filepath)], bundle: true, write: false, format: 'esm', target: 'es2023', }) return `` } else { const content = readFileSync(join(ROOT, filepath), 'utf8') return `<${tag}>\n${content}${tag}>` } }) html = html.replaceAll(/{{ include-article '(.*?)' }}/g, (_, filepath: string) => { const id = basename(filepath).slice(0, -extname(filepath).length) const content = readFileSync(join(ROOT, 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}`
},
)
return `\n${content}`
})
return minify(html, {
collapseWhitespace: true,
removeComments: true,
minifyCSS: true,
minifyJS: true,
})
},
},
],
})