Files
openswarm/backend/apps/outputs/webapp_template/frontend/vite.config.ts
T

96 lines
3.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import Pages from 'vite-plugin-pages';
import terminal from 'vite-plugin-terminal';
import path from 'path';
import os from 'os';
import fs from 'fs';
// Shared, hash-keyed vite optimization cache. Every webapp-template
// workspace shares its node_modules/ via a symlink to OpenSwarm's warm
// cache, AND now shares the optimized-deps output via this cache too —
// keyed on the hash of vite.config.ts + package.json so a real config
// or dep bump invalidates automatically. First workspace ever opened
// pays the ~1015s MUI pre-bundle; every subsequent workspace reuses
// the same `.vite-cache/deps/` and boots in under a second.
//
// Why this is safe (despite the earlier React-duplicate issue):
// 1. The skill prompt now mandates MUI path-imports — so every
// workspace ends up with the SAME, small, deduped optimizeDeps
// set. No more "workspace A pre-bundled @mui/material barrel,
// workspace B pre-bundled @mui/material/Button — collision."
// 2. resolve.dedupe pins react/react-dom/emotion to single instances
// from the symlinked node_modules root.
// 3. Vite's own metadata.json swap is atomic, so concurrent boots
// don't corrupt the cache.
function sharedViteCacheDir(): string {
const here = __dirname;
let digest = 'fallback';
try {
const crypto = require('crypto') as typeof import('crypto');
const hasher = crypto.createHash('sha256');
for (const f of ['vite.config.ts', 'package.json']) {
const p = path.join(here, f);
if (fs.existsSync(p)) hasher.update(fs.readFileSync(p));
}
digest = hasher.digest('hex').slice(0, 12);
} catch {
// Fall through — if hashing fails we still get a stable shared
// cache, just under one "fallback" key.
}
const base = process.env.OPENSWARM_VITE_CACHE_DIR
|| path.join(os.homedir(), '.openswarm', 'cache', 'webapp_template_vite_cache');
return path.join(base, digest);
}
export default defineConfig(({ mode }) => {
const backendPort = process.env.BACKEND_PORT;
const backendEnabled = backendPort && backendPort !== 'NONE';
return {
cacheDir: sharedViteCacheDir(),
plugins: [
react(),
Pages({ dirs: 'src/pages', extensions: ['tsx'] }),
// vite-plugin-terminal provides a `virtual:terminal/console` module
// that only exists in dev; loading it during `vite build` errors
// out, so the End-of-turn build-verify gate would fail on every
// brand-new workspace.
...(mode === 'development'
? [terminal({ console: 'terminal', output: ['terminal', 'console'] })]
: []),
],
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
// Force single instances of React and emotion — even if anything
// tries to resolve them from a deeper node_modules path (which
// could happen with symlinked node_modules + nested deps), vite
// pins to the one true copy at the symlinked top-level.
dedupe: ['react', 'react-dom', '@emotion/react', '@emotion/styled'],
},
define: {
'process.env.BACKEND_ENABLED': JSON.stringify(backendEnabled ? 'true' : ''),
},
server: {
host: '127.0.0.1',
port: Number(process.env.FRONTEND_PORT) || 3000,
strictPort: true,
open: false,
// Never show Vite's full-screen red error overlay: a transient bad import mid-build (the agent is
// still writing files) would flash a scary crash screen at the user. Errors still hit the console
// + terminal.log, which the agent reads to fix; the card shows a clean "building" state instead.
hmr: { overlay: false },
proxy: backendEnabled
? {
'/api': {
target: `http://localhost:${backendPort || 8324}`,
changeOrigin: true,
},
}
: undefined,
},
};
});