import fs from "fs/promises"; import {IndexHtmlTransformContext, Plugin, ServerOptions, UserConfig} from "vite"; let htmlCache: string | undefined = undefined; const getUrlFromServer = (server: ServerOptions): string => { const protocol = server.https ? 'https' : 'http'; const host = server.origin ?? 'localhost'; const port = server.port; return `${protocol}://${host}:${port}`; } const vitePluginWriteIndexToDisk: () => Plugin = () => ({ name: 'vite-plugin-write-index-to-disk', apply: 'serve', order: 'pre', config(config: UserConfig) { // warmup triggers transformIndexHtml on start if(config?.server?.warmup?.clientFiles && !config.server.warmup.clientFiles.includes('index.html')) { config.server.warmup.clientFiles.push('index.html') } else { if(!config.server) { config.server = {}; } config.server.warmup = { clientFiles: [ 'index.html' ] }; } }, async handleHotUpdate({ server, modules }) { if(modules.length === 0) { const url = getUrlFromServer(server.config.server); // fetch triggers transformIndexHtml after the initial warmup await fetch(url); } }, transformIndexHtml(html: string, ctx: IndexHtmlTransformContext) { if(!ctx.server) { return; } const {build, server} = ctx.server.config; const outDir = build.outDir; const url = getUrlFromServer(server); if(html !== htmlCache) { htmlCache = html; fs.writeFile( `./${outDir}/index.html`, html .replaceAll('src="', `src="${url}`) .replaceAll('href="', `href="${url}`) ); } }, }); export default vitePluginWriteIndexToDisk;