Skip to content

Vite 基础 ​

概述 ​

Vite(法语意为"快")是一个基于原生 ESM 的现代前端构建工具。由 Evan You(尤雨溪)创建,当前已成为前端构建工具的默认首选。

核心特点:

  • 开发服务器基于原生 ES Module,无需打包,秒级冷启动
  • HMR(热更新)速度极快,与项目大小无关
  • 开箱即用支持 TypeScript、JSX、CSS 预处理器等
  • 生产构建使用 Rollup(Vite 1-7)/ Rolldown(Vite 8+),确保最优打包

官网: vite.dev


核心原理 ​

1. 原生 ESM(ES Module) ​

Vite 最大的创新是开发阶段不打包,直接利用浏览器原生 ESM 能力。

工作流程:

浏览器请求 /src/main.ts
       ↓
Vite 服务器拦截请求
       ↓
按需编译(TS → JS / SFC → JS)
       ↓
返回 ESM 模块给浏览器
       ↓
浏览器自身处理依赖解析
浏览器请求 /src/main.ts
       ↓
Vite 服务器拦截请求
       ↓
按需编译(TS → JS / SFC → JS)
       ↓
返回 ESM 模块给浏览器
       ↓
浏览器自身处理依赖解析
  • 启动时不做任何模块处理,只有浏览器请求时才编译对应文件
  • 启动速度与项目规模无关(50 个模块 vs 5000 个模块一样快)

裸模块处理:

浏览器无法识别 import React from 'react' 中的 react。Vite 使用 es-module-lexer 解析所有 import,重写为有效 URL:

js
// 源码
import React from 'react'

// Vite 重写后
import React from '/@fs/workspace/node_modules/.vite/deps/react.js'
// 源码
import React from 'react'

// Vite 重写后
import React from '/@fs/workspace/node_modules/.vite/deps/react.js'

2. 依赖预构建 ​

虽然源码不打包,但第三方依赖需要特殊处理。原因:

问题说明
CJS/UMD 兼容npm 包大量使用 CommonJS,浏览器无法直接运行
请求数量过多lodash-es 有 600+ 文件,每个一个请求
模块格式不统一需要统一转为 ESM

预构建流程(使用 esbuild,Go 编写,比 JS 打包器快 10-100 倍):

  1. 扫描源码中的裸模块导入
  2. esbuild 将依赖合并为少量 ESM 文件
  3. 输出到 node_modules/.vite/deps/
  4. 根据 lockfile 哈希判断是否需要重建(强缓存)

仅在首次启动或依赖变更时触发

3. HMR(热更新) ​

核心流程:

文件修改
  ↓
① chokidar 监听文件变更
  ↓
② 确定受影响的模块边界
  ↓
③ 仅对变更文件按需编译
  ↓
④ WebSocket 推送更新消息给浏览器
  ↓
⑤ 客户端重新请求该模块 (?t=timestamp)
  ↓
⑥ 执行新模块 → hot.accept() 回调 → 局部替换
文件修改
  ↓
① chokidar 监听文件变更
  ↓
② 确定受影响的模块边界
  ↓
③ 仅对变更文件按需编译
  ↓
④ WebSocket 推送更新消息给浏览器
  ↓
⑤ 客户端重新请求该模块 (?t=timestamp)
  ↓
⑥ 执行新模块 → hot.accept() 回调 → 局部替换

HMR API:

js
if (import.meta.hot) {
  // 接受自身更新
  import.meta.hot.accept((newModule) => {
    console.log('模块已更新:', newModule)
  })

  // 接受依赖更新
  import.meta.hot.accept('./dependency.js', (newDep) => {
    updateDependency(newDep)
  })

  // 清理副作用
  import.meta.hot.dispose(() => {
    clearInterval(timer)
  })
}
if (import.meta.hot) {
  // 接受自身更新
  import.meta.hot.accept((newModule) => {
    console.log('模块已更新:', newModule)
  })

  // 接受依赖更新
  import.meta.hot.accept('./dependency.js', (newDep) => {
    updateDependency(newDep)
  })

  // 清理副作用
  import.meta.hot.dispose(() => {
    clearInterval(timer)
  })
}

Vite vs Webpack ​

性能对比 ​

维度ViteWebpack
冷启动~0.8s(按需编译)8-20s(全量打包)
HMR(JS)< 100ms800ms - 1.2s
HMR(CSS)< 50ms~1.8s
内存占用~480 MB~1.2 GB
生产构建~6.3s~18.5s
打包体积~465 KB(gzip)~480-809 KB(gzip)

核心差异 ​

方面ViteWebpack
开发策略按需编译(ESM)全量打包
配置开箱即用,配置简洁高度可配,但繁重
TS 支持原生,内置 esbuild需 ts-loader 或 babel
CSS 预处理器原生支持需 loader
代码分割Rollup/Rolldown 自动需手动 splitChunks
插件生态兼容 Rollup 插件自成一派

选型建议 ​

选 Vite:

  • 新项目(Vue 3、React 18+、Svelte、Solid)
  • 仅支持现代浏览器
  • 追求开发体验和迭代速度

选 Webpack:

  • 大型存量项目,有大量自定义 Webpack 配置
  • 需要 Module Federation(微前端)
  • 需要兼容 IE11

Vite 8 + Rolldown(2026) ​

Vite 8 于 2026 年 3 月发布,引入 Rust 编写的 Rolldown 统一打包器:

  • 双引擎合一:取代 esbuild(dev)+ Rollup(prod)架构
  • 构建速度:生产构建 10-30× 提升(72s → 3s)
  • 包体积:从 ~50 MB 降至 ~18 MB
  • 插件兼容:99%+ Rollup 插件可继续使用

迁移要点:build.rollupOptions → build.rolldownOptions