118 lines
4.6 KiB
TypeScript
118 lines
4.6 KiB
TypeScript
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 `<script>
|
|
window.__ENV__ = {
|
|
CDN: "${ctx.server ? '/cdn' : 'https://cdn.gifuu.pancakz.net'}",
|
|
API: "${ctx.server ? '/api' : 'https://api.gifuu.pancakz.net'}",
|
|
WEB: "${ctx.server ? '' : 'https://gifuu.pancakz.net'}",
|
|
}
|
|
</script>`
|
|
})
|
|
.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(
|
|
/<pre([^>]*)>\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 `<pre${attributes}>${trimmed}</pre>`
|
|
},
|
|
)
|
|
const inlined = `<template class="article" id="${id}">\n${content}</template>`
|
|
|
|
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,
|
|
})
|
|
},
|
|
},
|
|
],
|
|
})
|