Frontend Development 9 min read

Understanding Vite’s Development Server Architecture and Pre‑bundling Mechanism

This article explains how Vite achieves fast development by serving ES modules directly, using a connect‑based dev server with plugin‑driven transforms, pre‑bundling dependencies via esbuild, generating hash‑based cache keys, and reusing the same plugins in Rollup for production builds.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Understanding Vite’s Development Server Architecture and Pre‑bundling Mechanism

Vite is a modern front‑end build tool that is noticeably faster than webpack because it does not bundle source files during development; instead it serves them as native ES modules.

Creating a Vite project is as simple as running npx create-vite , installing dependencies with npm install , and starting the dev server with npm run dev . The server launches a Connect‑based HTTP service that watches file changes.

In the dev environment Vite serves files like main.tsx and App.tsx directly to the browser using <script type="module"> tags, performing only on‑the‑fly compilation (e.g., TypeScript or JSX) without creating a bundled bundle.

An example index2.html loads a module aaa.js , which imports a function from bbb.js . Both modules are fetched, compiled, and executed by the browser, demonstrating Vite’s “no‑bundle” approach.

The dev server parses HTML, discovers all <script type="module"> entries, and applies a series of plugins. Plugins such as the CSS plugin, the esbuild plugin for TS/JS, and the import‑analysis plugin each implement a transform hook that processes only the resources they understand.

Because many npm packages are authored in CommonJS, Vite performs a pre‑bundling step (called “deps‑optimize”) that converts those packages to ESM and bundles them once using esbuild. This reduces the number of HTTP requests and avoids runtime CommonJS‑to‑ESM conversion.

During pre‑bundling, esbuild scans the dependency graph, flattens paths (e.g., converting react-dom/client to react-dom_client ), and outputs ESM files into node_modules/.vite . It also generates a _metadata.json file containing hash values for each pre‑bundled module.

Vite attaches the hash as a query string to the module URL and serves it with a long max‑age cache header. When the lockfile or Vite config changes, Vite rebuilds the pre‑bundles, updates the hash, and forces the browser to fetch the new version.

For production builds Vite delegates to Rollup. Because Vite plugins are compatible with Rollup plugins, the same transformation logic used in development is applied during the final bundle, guaranteeing consistency between dev and prod outputs.

Hot Module Replacement (HMR) is implemented with chokidar watching source files and a WebSocket connection that notifies the browser of updates. Upon receiving an HMR message, the browser reloads the affected module with a timestamped request.

In summary, Vite’s architecture combines a lightweight dev server that serves ES modules, esbuild‑driven pre‑bundling for fast dependency handling, hash‑based strong caching, Rollup‑compatible plugins for production, and a WebSocket‑based HMR system, delivering a seamless development experience.

frontendJavaScriptviteRollupDev ServeresbuildPre‑bundlingHot Module Replacement
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.