Skip to content

Vite bundling

Terminal window
npm run dev # Vite dev server with HMR
npm run build # production bundle written to dist/
npm run preview # serve the built output

The dev server transforms modules on demand. The production build resolves the full graph, fingerprints assets and writes static files.

LocationProcessingUse for
public/Copied unchangedrobots.txt, _headers, favicons, fixed downloads
src/assets/Imported, hashed, optimisableImages, fonts, SVGs used by components

Imported assets get content hashes in their filenames, so they can be cached indefinitely. Public files keep their exact paths, which is useful for files that must be served at a fixed URL.

---
import logo from '@assets/logo.svg';
---
<img src={logo.src} alt="Jampuk Intelligence" width={logo.width} height={logo.height} />

Define aliases once in tsconfig.json so the editor and Vite agree:

{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@components/*": ["src/components/*"],
"@layouts/*": ["src/layouts/*"],
"@assets/*": ["src/assets/*"],
"@lib/*": ["src/lib/*"],
"@data/*": ["src/data/*"]
}
}
}

Astro reads these aliases automatically. Avoid duplicating them in a separate Vite config unless a plugin needs them before Astro resolves the TypeScript configuration.

Only variables prefixed with PUBLIC_ are exposed to client code. They are inlined at build time, so a static build is environment-specific.

Terminal window
PUBLIC_SITE_URL=https://www.example.com
PUBLIC_GA_MEASUREMENT_ID=G-XXXXXXX

Never put secrets in a PUBLIC_ variable. Anything inlined into the bundle is public.

Vite splits shared dependencies automatically. Add manual chunks only when a large dependency is duplicated or a route bundle grows unexpectedly:

astro.config.mjs
export default defineConfig({
vite: {
build: {
rollupOptions: {
output: {
manualChunks: {
vendor: ['react', 'react-dom'],
},
},
},
},
},
});

Inspect the output before and after a change. A manual chunk can improve caching or make the first load worse if it pulls code into the critical path.

Astro sets a modern browser target by default. Lower it only when analytics show a real population of older browsers. Common issues:

  • A missing alias points at the wrong directory.
  • A PUBLIC_ variable is undefined because it was set after the build.
  • A large dependency appears in every route because it is imported from a shared layout.
  • A public/ asset is stale because the filename did not change.

For asset optimisation, see Sharp images. For framework-level rendering, see Static site generation.