import tailwindcss from "@tailwindcss/vite"; import fs from "fs"; import { lookup as lookupMime } from "mrmime"; import path from "path"; import { fileURLToPath } from "url"; import { defineConfig, loadEnv, type Plugin } from "vite"; import { createHtmlPlugin } from "vite-plugin-html"; import { type AssetManifest, buildAssetUrl, rewriteAssetsForCdn, } from "./src/core/AssetUrls"; import { buildPublicAssetManifest, copyRootPublicFiles, createHashedPublicAssetFiles, getProprietaryDir, getResourcesDir, writePublicAssetManifest, } from "./src/server/PublicAssetManifest"; // Vite already handles these, but its good practice to define them explicitly const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); function serveProprietaryDir( proprietaryDir: string, resourcesDir: string, ): Plugin { return { name: "serve-proprietary-dir", configureServer(server) { // Must run before Vite's htmlFallback; skip when resources/ has the file // so publicDir keeps precedence. server.middlewares.use((req, res, next) => { if (!req.url) return next(); const rel = decodeURIComponent( new URL(req.url, "http://x").pathname, ).replace(/^\//, ""); if (rel.includes("..")) return next(); if (fs.existsSync(path.join(resourcesDir, rel))) return next(); const filePath = path.join(proprietaryDir, rel); if (!fs.existsSync(filePath) || !fs.statSync(filePath).isFile()) return next(); const mime = lookupMime(filePath); if (mime) res.setHeader("Content-Type", mime); res.setHeader("Cache-Control", "no-store"); fs.createReadStream(filePath).pipe(res); }); }, }; } export default defineConfig(({ mode }) => { const env = loadEnv(mode, process.cwd(), ""); const isProduction = mode === "production"; const resourcesDir = getResourcesDir(__dirname); const proprietaryDir = getProprietaryDir(__dirname); const sourceDirs = [resourcesDir, proprietaryDir]; const assetManifest: AssetManifest = isProduction ? buildPublicAssetManifest(sourceDirs) : {}; const cdnBase = env.CDN_BASE ?? ""; const htmlAssetData = { assetManifest: JSON.stringify(assetManifest), cdnBase: JSON.stringify(cdnBase), gameEnv: JSON.stringify(env.GAME_ENV ?? "dev"), manifestHref: buildAssetUrl("manifest.json", assetManifest, cdnBase), faviconHref: buildAssetUrl("images/Favicon.svg", assetManifest, cdnBase), gameplayScreenshotUrl: buildAssetUrl( "images/GameplayScreenshot.png", assetManifest, cdnBase, ), backgroundImageUrl: buildAssetUrl( "images/background.webp", assetManifest, cdnBase, ), desktopLogoImageUrl: buildAssetUrl( "images/OpenFront.png", assetManifest, cdnBase, ), mobileLogoImageUrl: buildAssetUrl("images/OF.png", assetManifest, cdnBase), }; // Vite's HTML transform replaces the source