Vite
A Vite plugin suite that bundles six SPA build-time conveniences into one install. Typed env loading with NODE_ENV resolution, in-HTML env interpolation, tsconfig path mirroring, auto-open dev server, production base URL, post-build zip — plus optional .htaccess generation and pre-render integration. Build-time only; no runtime code ships to the browser.
Highlighted features
Typed env loading
Reads .env.<environment> via @mongez/dotenv — gets numbers, booleans, null as real primitives, not strings.
In-HTML env interpolation
<title>APP_NAME</title> in index.html → replaced at build time with the env value. Customisable prefix/suffix.
tsconfig path mirroring
Copies compilerOptions.paths into resolve.alias automatically — TypeScript and Vite always agree on module resolution.
Production base URL
Reads PUBLIC_URL (or your chosen env key) during vite build and sets config.base. Deploy to subpaths without per-environment config files.
Post-build zip + .htaccess
Optional zip of dist/ for deploy, optional Apache SPA fallback rules — “vite build” → “scp the zip” works without extra glue.
Pre-render integration
Route crawlers (Google, FB scrapers) to your pre-render service via prerender.php. Same SEO win as SSR without the SSR framework.
Install
npm install -D @mongez/viteyarn add -D @mongez/vitepnpm add -D @mongez/vitePeer dep: vite >= 5.0.0. Install as a dev dependency — @mongez/vite is build-time only.
Quick peek
import { defineConfig } from "vite";import react from "@vitejs/plugin-react";import mongezVite from "@mongez/vite";
export default defineConfig({ plugins: [ mongezVite({ htaccess: true, // emit Apache SPA fallback rules preRender: { url: "https://render.io" }, // route crawlers to a prerender service }), react(), ],});Register the plugin in vite.config.ts. The default profile turns on env loading, HTML interpolation, tsconfig aliases, auto-open dev, production base URL, and post-build zip — all driven by your .env.<environment> files.
Behavioural defaults
| Option | Default | Why |
|---|---|---|
autoOpenBrowser | true | Quality-of-life — most SPA devs want this |
linkTsconfigPaths / tsconfigAlias | true | Keeps TS + Vite in sync without a second plugin |
compressBuild | true | vite build → scp the zip is a common Mongez deploy |
htaccess | false | Apache-specific — defaults off |
preRender | false | Requires an external service — opt in |
envBaseUrlKey | "PUBLIC_URL" | Convention from CRA / Next.js |
htmlEnvPrefix / htmlEnvSuffix | "__" | Visible at a glance, doesn’t trip URL parsers |
The two-phase lifecycle
mongezVite() │ ├─ config hook (Vite calls once) │ ├─ resolveAutoOpenBrowser (server.open) │ ├─ resolveTsConfigAlias (resolve.alias) │ ├─ resolveEnvironmentVariables (loadEnv → @mongez/dotenv store) │ └─ resolveOtherConfig (config.base, optimizeDeps) │ ├─ transformIndexHtml (per HTML file Vite emits) │ └─ replace __KEY__ tokens │ └─ writeBundle (Vite calls once after build) ├─ generateHtaccess (emit .htaccess + prerender.php) └─ compressBuild (zip the output dir)The config hook does most of the work. By the time it returns, the resolved Vite config has server.open, config.base, resolve.alias, and optimizeDeps filled in (when the user didn’t already set them).
Scope boundaries
| Concern | Lives in | Why |
|---|---|---|
.env parsing | @mongez/dotenv | One slice — file IO and coercion |
| Bundle / chunk / asset transforms | Vite itself | Use Vite’s plugin API directly |
| Service worker / PWA / image optimisation | Separate Vite plugins | Out of scope |
| Runtime state, hooks, queries | @mongez/atom family | Unrelated; this is build-time only |
Where to go next
- Env loading —
.env.<environment>resolution, type coercion - Env in HTML —
__KEY__interpolation rules - Production base URL —
envBaseUrlKey, when the plugin does NOT touchconfig.base - tsconfig aliases — path mirroring
- Auto-open browser — when the plugin does nothing
- Build ZIP — zip emission, output paths
- .htaccess — Apache SPA fallback rules
- Prerender — crawler routing setup
- Recipes — common patterns