1
0
peddlers-of-ketran/client/vite.config.js

135 lines
5.9 KiB
JavaScript

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import fs from 'fs';
const httpsEnv = (process.env.HTTPS || '').toLowerCase();
const useHttps = httpsEnv === 'true' || httpsEnv === '1';
import tsconfigPaths from 'vite-tsconfig-paths'
// Forward browser console messages to the dev server logs so container logs
// show frontend console output. This is enabled only when running the dev
// server (not for production builds).
import { consoleForwardPlugin } from './src/plugins/vite-console-forward-plugin.js'
// If custom cert paths are provided via env, use them; otherwise let Vite handle a self-signed cert when true.
const httpsOption = useHttps
? (process.env.VITE_HTTPS_KEY && process.env.VITE_HTTPS_CERT
? {
key: fs.readFileSync(process.env.VITE_HTTPS_KEY),
cert: fs.readFileSync(process.env.VITE_HTTPS_CERT)
}
: true)
: false;
// Determine base path from env (PUBLIC_URL or VITE_BASEPATH). Keep a
// normalized value with a leading slash and a trailing slash (e.g.
// '/ketr.ketran/'), or just '/' when empty/root. This matches how the
// built client writes a <base href="/ketr.ketran/"> and avoids dev-server
// mismatches that lead to helpful-but-confusing 404 text responses.
const rawBase = process.env.PUBLIC_URL || process.env.VITE_BASEPATH || '/';
let normalizedBase = rawBase || '/';
if (normalizedBase.length > 1) {
// Ensure leading slash and single trailing slash
normalizedBase = normalizedBase.replace(/^\/+/, '/').replace(/\/+$/, '') + '/';
if (!normalizedBase.startsWith('/')) normalizedBase = '/' + normalizedBase;
} else {
// Root
normalizedBase = '/';
}
export default defineConfig({
// Base public path when served in dev or production. Allow overriding
// via environment variables (PUBLIC_URL or VITE_BASEPATH).
base: normalizedBase,
plugins: [
react(),
tsconfigPaths(),
// Only enable the console forwarding plugin while running the dev
// server (NODE_ENV typically not 'production'). It is safe to include
// here because the plugin's transformIndexHtml is a no-op in
// production by checking NODE_ENV.
consoleForwardPlugin({ enabled: false, levels: ["log", "warn", "error"] }),
// Dev-only plugin: when the dev server receives requests that are
// already prefixed with the base (e.g. /ketr.ketran/assets/...), strip
// the prefix so Vite can serve the underlying files from /assets/...
{
name: "strip-basepath-for-dev",
configureServer(server) {
// Only install the middleware when a non-root base is configured
if (!normalizedBase || normalizedBase === "/") return;
server.middlewares.use((req, res, next) => {
try {
// Log incoming base-prefixed requests for debugging only. Do NOT
// rewrite the URL — Vite is configured with the same `base` so it
// expects requests to include the base. Rewriting to remove the
// base causes Vite to return an explanatory 404 ("The server is
// configured with a public base URL...") for paths like
// '/@vite/client'. Let Vite handle the request as-is.
if (req.url && req.url.indexOf(normalizedBase) === 0) {
if (req.url === normalizedBase) {
console.log(`[vite] incoming url (base root): ${req.url} (base ${normalizedBase})`);
} else {
console.log(`[vite] incoming url: ${req.url} (base ${normalizedBase})`);
// If the incoming request is for a public asset (e.g.
// '/<base>/assets/...'), strip the base so Vite can
// serve the static file from '/assets/...'. We only rewrite
// asset paths here to avoid interfering with module paths
// and HMR endpoints which Vite already serves correctly
// when the server `base` is configured.
const assetsPrefix = normalizedBase.replace(/\/$/, "") + "/assets/";
if (req.url.indexOf(assetsPrefix) === 0) {
const original = req.url;
// Preserve the base and change '/assets/' to '/gfx/' so the
// dev server serves files from public/gfx which are exposed at
// '/<base>/gfx/...'. Example: '/ketr.ketran/assets/gfx/x' ->
// '/ketr.ketran/gfx/x'.
const baseNoTrail = normalizedBase.replace(/\/$/, "");
req.url = req.url.replace(new RegExp("^" + baseNoTrail + "/assets/"), baseNoTrail + "/gfx/");
console.log(`[vite] rewritten asset ${original} -> ${req.url}`);
}
}
}
} catch (e) {
// ignore and continue
}
next();
});
},
},
],
build: {
outDir: "build",
},
server: {
host: process.env.HOST || "0.0.0.0",
port: Number(process.env.PORT) || 3001,
https: httpsOption,
proxy: {
// Support requests that already include the basePath (/ketr.ketran/api)
// and requests that use the shorter /api path. Both should be forwarded
// to the backend server which serves the API under /ketr.ketran/api.
"/ketr.ketran/api": {
target: "http://pok-server:8930",
changeOrigin: true,
ws: true,
secure: false,
},
"/api": {
target: "http://pok-server:8930",
changeOrigin: true,
ws: true,
secure: false,
rewrite: (path) => `/ketr.ketran${path}`,
},
},
// HMR options: advertise the external hostname and port so browsers
// accessing via `battle-linux.ketrenos.com` can connect to the websocket.
// The certs mounted into the container must be trusted by the browser.
hmr: {
host: process.env.VITE_HMR_HOST || "battle-linux.ketrenos.com",
port: Number(process.env.VITE_HMR_PORT) || 3001,
protocol: process.env.VITE_HMR_PROTOCOL || "wss",
},
},
});