Frontend Development 21 min read

How Vite Transforms Frontend Development: Fast Startup, ES Modules & HMR

This article explains Vite’s architecture, from its fast cold‑start and native ES‑module development server to its plugin system, build process, handling of Vue single‑file components, CSS preprocessing, and hot‑module replacement, showing how it differs from traditional bundlers like webpack.

Taobao Frontend Technology
Taobao Frontend Technology
Taobao Frontend Technology
How Vite Transforms Frontend Development: Fast Startup, ES Modules & HMR

Vite is a web development tool created by Vue author尤雨溪, offering fast cold start, instant module hot‑update, and true on‑demand compilation.

Vite is a development server based on native browser ES imports. It parses imports in the browser, compiles on demand on the server, completely skips bundling, and provides Vue file support with hot updates that don’t slow down as modules increase. For production it uses Rollup. Although still rough, the direction has great potential.

Vite builds on the idea of using native ES modules in the browser, similar to Snowpack, and may revive this development style.

Vite Usage

Initialize a project with npm or yarn:

<code>$ yarn create vite-app <project-name>
$ cd <project-name>
$ yarn
$ yarn dev</code>

The generated project structure is minimal:

<code>|____node_modules
|____App.vue // application entry
|____index.html // page entry
|____vite.config.js // config file
|____package.json</code>

Run

yarn dev

to start the application.

Command Parsing

Vite parses CLI commands using

minimist

. The core function is:

<code>function resolveOptions() {
  // command can be dev/build/optimize
  if (argv._[0]) {
    argv.command = argv._[0];
  }
  return argv;
}</code>

Based on

options.command

, Vite runs

runServe

for development or

runBuild

for production.

Server Implementation

Vite uses Koa as the web server and

clmloader

to watch file changes. It creates a context object injected into each plugin:

<code>interface ServerPluginContext {
  root: string;
  app: Koa;
  server: Server;
  watcher: HMRWatcher;
  resolver: InternalResolver;
  config: ServerConfig;
}

type ServerPlugin = (ctx: ServerPluginContext) => void;</code>

A sample plugin that intercepts JSON files:

<code>interface ServerPluginContext { root: string; app: Koa; server: Server; watcher: HMRWatcher; resolver: InternalResolver; config: ServerConfig; }

type ServerPlugin = (ctx: ServerPluginContext) => void;

const JsonInterceptPlugin: ServerPlugin = ({app}) => {
  app.use(async (ctx, next) => {
    await next();
    if (ctx.path.endsWith('.json') && ctx.body) {
      ctx.type = 'js';
      ctx.body = `export default json`;
    }
  });
};</code>

Plugin System

Plugins receive the context components and can add middleware, watch files, or perform other tasks. Core plugins include:

User‑injected custom plugins

hmrPlugin – handles hot module replacement

htmlRewritePlugin – rewrites script tags in HTML

moduleRewritePlugin – rewrites import paths

moduleResolvePlugin – resolves module content

vuePlugin – processes Vue single‑file components

esbuildPlugin – uses esbuild for resource handling

assetPathPlugin – processes static assets

serveStaticPlugin – serves static files

cssPlugin – handles CSS/LESS/SASS imports

Build Process

For production, Vite uses Rollup. The build directory mirrors the server structure and exports a

runBuild

method with Rollup‑specific plugins.

ES Module Basics

Modern browsers (except IE11) support ES modules with

export

and

import

statements inside

&lt;script type="module"&gt;

tags.

<code>&lt;script type="module"&gt;
  import { bar } from './bar.js';
&lt;/script&gt;</code>

In

bar.js

:

<code>export const bar = 'bar';</code>

Vite’s ES Module Handling

Vite runs a Koa middleware that parses the request body, uses

es-module-lexer

to find imports, rewrites absolute imports to the

@modules

prefix, and returns the transformed code.

<code>if (!options.command || options.command === 'serve') {
  runServe(options);
} else if (options.command === 'build') {
  runBuild(options);
} else if (options.command === 'optimize') {
  runOptimize(options);
}</code>

@modules

Browser ES modules cannot directly import packages from

node_modules

. Vite rewrites imports like

import { createApp } from 'vue'

to

import { createApp } from '/@modules/vue'

, allowing the server to resolve the package and serve it as an ES module.

Module Resolution

When a request matches

@modules

, Vite uses

require('module')

to obtain the package’s export and returns it to the browser. For CommonJS packages, Vite’s

optimize

command recompiles them with Rollup into ES‑module format and caches the result.

<code>// vite.config.js
module.exports = {
  optimizeDeps: {
    include: ["lodash"]
  }
};</code>

Vue Single‑File Component (SFC) Compilation

Vite parses .vue files, splits them into script, style, and template parts, and serves each part via separate requests. The main compilation generates code like:

<code>import { updateStyle } from "/vite/hmr"
updateStyle("c44b8200-0", "/App.vue?type=style&index=0")
const __script = { /* script content */ }
import { render as __render } from "/App.vue?type=template"
__script.render = __render
export default __script</code>

This approach enables on‑demand loading of each part without a full bundle.

CSS Handling

Vite’s

cssPlugin

detects files with extensions like .less, .sass, .scss, .styl, and processes them with PostCSS, allowing the same workflow as webpack for CSS preprocessing.

Hot Module Replacement (HMR)

Vite implements HMR via a WebSocket client (

vite/hmr

) and server middleware. The client listens for message types such as

vue-reload

,

vue-rerender

,

vue-style-update

,

style-update

,

js-update

, and

full-reload

, applying the appropriate updates in the browser.

<code>// Server side HMR middleware
app.use(async (ctx, next) => {
  if (ctx.path === '/vite/hmr') {
    ctx.type = 'js';
    ctx.status = 200;
    ctx.body = hmrClient;
  }
});</code>

On file change, the watcher triggers either

handleVueReload

(for .vue files) or

handleJSReload

(for other modules), sending WebSocket messages to the client to reload or re‑render the affected parts.

Conclusion

The article demonstrates Vite’s startup chain and core principles, highlighting its fast development experience, on‑demand ES‑module handling, plugin architecture, and efficient HMR, showing why it is an exciting alternative to traditional bundlers.

Vite illustration
Vite illustration
Vite architecture
Vite architecture
Vite context diagram
Vite context diagram
Browser ES module support
Browser ES module support
Optimize command
Optimize command
Frontend DevelopmentBuild toolsViteES Moduleshot module replacement
Taobao Frontend Technology
Written by

Taobao Frontend Technology

The frontend landscape is constantly evolving, with rapid innovations across familiar languages. Like us, your understanding of the frontend is continually refreshed. Join us on Taobao, a vibrant, all‑encompassing platform, to uncover limitless potential.

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.