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.
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 devto 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
runServefor development or
runBuildfor production.
Server Implementation
Vite uses Koa as the web server and
clmloaderto 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
runBuildmethod with Rollup‑specific plugins.
ES Module Basics
Modern browsers (except IE11) support ES modules with
exportand
importstatements inside
<script type="module">tags.
<code><script type="module">
import { bar } from './bar.js';
</script></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-lexerto find imports, rewrites absolute imports to the
@modulesprefix, 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
optimizecommand 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
cssPlugindetects 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.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.