55 lines
2.1 KiB
TypeScript
55 lines
2.1 KiB
TypeScript
import { defineConfig } from 'vite';
|
|
import react from '@vitejs/plugin-react';
|
|
|
|
// Minimal typing for process.env so we don't need @types/node just for this.
|
|
declare const process: { env: Record<string, string | undefined> };
|
|
|
|
// Where a `vite dev` session sends its API calls. Playpen prefers 8420 and walks
|
|
// upward if it's taken, so this is right unless you have two windows open — in
|
|
// which case read the real one out of PLAYPEN_REVIEW_URL in any of its terminals.
|
|
const apiPort = process.env.PLAYPEN_REVIEW_PORT || '8420';
|
|
const apiTarget = `http://127.0.0.1:${apiPort}`;
|
|
|
|
export default defineConfig({
|
|
plugins: [react()],
|
|
|
|
// Relative asset URLs, because the page is served from a tab's path
|
|
// (`/t/tab3/`) and not from the server root. With an absolute base the
|
|
// browser would ask for `/assets/app.js` and get the tab router instead.
|
|
base: './',
|
|
|
|
server: {
|
|
port: 5173,
|
|
proxy: {
|
|
// A tab's own API and event stream. Matched as a regex so the HTML at
|
|
// `/t/<id>/` still comes from Vite — only the calls underneath it are
|
|
// forwarded, which is what lets hot reloading work against a live review.
|
|
//
|
|
// Open http://localhost:5173/t/<tabId>/ to develop against a real tab.
|
|
'^/t/[^/]+/api': { target: apiTarget, changeOrigin: true },
|
|
// The app-wide endpoints: /api/tabs and /api/health.
|
|
'/api': { target: apiTarget, changeOrigin: true },
|
|
},
|
|
},
|
|
|
|
build: {
|
|
outDir: 'dist',
|
|
emptyOutDir: true,
|
|
|
|
// Fixed filenames rather than Vite's content hashes. The bundle is embedded
|
|
// in the playpen binary (src/review/assets.zig), so the Zig side has to be
|
|
// able to name the files at compile time — and cache busting buys nothing
|
|
// for a bundle that only changes when the binary does.
|
|
rollupOptions: {
|
|
output: {
|
|
entryFileNames: 'assets/app.js',
|
|
chunkFileNames: 'assets/app.js',
|
|
assetFileNames: 'assets/app[extname]',
|
|
// One file, so there is one name to embed. The app is a few hundred
|
|
// kilobytes loaded from localhost; splitting it saves nothing.
|
|
manualChunks: undefined,
|
|
},
|
|
},
|
|
},
|
|
});
|