import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { readFileSync } from 'node:fs'; import { themeStoragePlugin } from '../vite-theme-plugin'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const packageJson = JSON.parse(readFileSync(path.resolve(__dirname, 'package.json'), 'utf-8')); const reactScanToggle = (process.env.VITE_ENABLE_REACT_SCAN ?? '').toLowerCase(); const enableReactScan = reactScanToggle === '1' || reactScanToggle === 'true' || reactScanToggle === 'on' || reactScanToggle === 'yes'; export default defineConfig({ root: path.resolve(__dirname, '.'), plugins: [ react({ babel: { plugins: ['babel-plugin-react-compiler'], }, }), { name: 'inject-react-scan-script', transformIndexHtml() { if (!enableReactScan) { return; } return [ { tag: 'script', attrs: { crossorigin: 'anonymous', src: '//unpkg.com/react-scan/dist/auto.global.js', }, injectTo: 'head-prepend', }, ]; }, }, themeStoragePlugin(), ], resolve: { alias: [ { find: '@opencode-ai/sdk/v2', replacement: path.resolve(__dirname, '../node_modules/@opencode-ai/sdk/dist/v2/client.js') }, { find: '@openchamber/ui', replacement: path.resolve(__dirname, '../ui/src') }, { find: '@web', replacement: path.resolve(__dirname, './src') }, { find: '@', replacement: path.resolve(__dirname, '../ui/src') }, ], }, worker: { format: 'es', }, define: { 'process.env': {}, global: 'globalThis', __APP_VERSION__: JSON.stringify(packageJson.version), }, optimizeDeps: { include: ['@opencode-ai/sdk/v2'], }, server: { port: 5173, proxy: { '/auth': { target: `http://127.0.0.1:${process.env.OPENCHAMBER_PORT || 3001}`, changeOrigin: true, }, '/health': { target: `http://127.0.0.1:${process.env.OPENCHAMBER_PORT || 3001}`, changeOrigin: true, }, '/api': { target: `http://127.0.0.1:${process.env.OPENCHAMBER_PORT || 3001}`, changeOrigin: true, }, }, }, build: { outDir: path.resolve(__dirname, 'dist'), emptyOutDir: true, chunkSizeWarningLimit: 1200, rollupOptions: { external: ['node:child_process', 'node:fs', 'node:path', 'node:url'], output: { manualChunks(id) { if (!id.includes('node_modules')) return undefined; const match = id.split('node_modules/')[1]; if (!match) return undefined; const segments = match.split('/'); const packageName = match.startsWith('@') ? `${segments[0]}/${segments[1]}` : segments[0]; if (packageName === 'react' || packageName === 'react-dom') return 'vendor-react'; if (packageName === 'zustand' || packageName === 'zustand/middleware') return 'vendor-zustand'; if (packageName === '@opencode-ai/sdk') return 'vendor-opencode-sdk'; if (packageName.includes('remark') || packageName.includes('rehype') || packageName === 'react-markdown') return 'vendor-markdown'; if (packageName.startsWith('@radix-ui')) return 'vendor-radix'; if (packageName.includes('react-syntax-highlighter') || packageName.includes('highlight.js')) return 'vendor-syntax'; const sanitized = packageName.replace(/^@/, '').replace(/\//g, '-'); return `vendor-${sanitized}`; }, }, }, }, });