import { defineConfig, loadEnv } from 'vite'; import laravel from 'laravel-vite-plugin'; import tailwindcss from '@tailwindcss/vite'; export default defineConfig(({ mode }) => { // Read the .env FILE via Vite's loadEnv — NOT process.env: the dev container bind-mounts .env but // does not export it into the process environment, so process.env.VITE_HMR_HOST is always empty // there. VITE_HMR_HOST is the address the BROWSER uses to reach the dev VM (HMR websocket + the // hot-asset origin). It lives ONLY in the gitignored dev .env, so no private/internal address is // committed or baked into the shipped image. Unset → undefined → Vite infers it from the request // host (never a broken hard 'localhost' that 404s the CSS/JS on a remote dev box). const env = loadEnv(mode, process.cwd(), 'VITE_'); return { plugins: [ laravel({ input: ['resources/css/app.css', 'resources/js/app.js'], refresh: true, }), tailwindcss(), ], server: { // Bind all interfaces inside the container; the browser reaches the VM. host: '0.0.0.0', port: 5173, strictPort: true, cors: true, // Remote HMR: hot file + websocket point at the dev VM (VITE_HMR_HOST), not 0.0.0.0. // Dev-only — prod builds assets, there is no HMR server. hmr: { host: env.VITE_HMR_HOST || undefined, }, // The repo is rooted in $HOME — keep the watcher off heavy/irrelevant trees. watch: { ignored: [ '**/vendor/**', '**/node_modules/**', '**/storage/**', '**/.git/**', '**/.cache/**', '**/.npm/**', '**/.vscode-server/**', '**/.dotnet/**', '**/.composer/**', '**/.config/**', '**/.claude/**', '**/.local/**', ], }, }, }; });