Vite 原理与 Vue 项目实践

1️⃣ Vite 核心原理:两套完全不同的世界观 🧠

1.1 Vite 的一句话架构定义

Vite = 基于浏览器原生 ESM 的开发服务器 + 基于 Rollup 的生产构建

注意:

👉 开发(dev)和生产(build)是两条完全不同的技术路线

这是 Vite 和 Webpack 最大的分水岭。

1.2 Vite Dev Server 的核心思想:

"不打包,只服务"

Webpack dev:

  • 先把整个依赖图打包成 bundle
  • 再启动 dev server
  • 改一行代码 → 重新构建依赖图的一部分

Vite dev:

  • 利用浏览器原生支持的 ES Module
  • 每个模块都是一个 HTTP 请求
  • 只在浏览器"请求到它"的时候,才处理这个模块

👉 这意味着:
Vite 在开发时,根本没有"全量打包"这一步

1.3 Vite 的 dev 请求流程(关键)

当浏览器访问页面时:

txt 复制代码
index.html
 ↓
<script type="module" src="/src/main.ts">
 ↓
import App from './App.vue'
 ↓
import { ref } from 'vue'

Vite 做的事情只有三件:

1️⃣ 拦截浏览器请求

2️⃣ 按需编译(TS / Vue / JSX)

3️⃣ 返回浏览器能执行的 ESM 代码

没有 bundle,没有 chunk,没有 graph traversal。

2️⃣ 冷启动优势:为什么 Vite 能做到"秒开"?⚡

2.1 Webpack 冷启动慢在哪?

Webpack 启动时必须做:

  • 解析入口
  • 构建完整依赖图
  • loader 转换
  • 打包成 bundle
  • 输出到内存
  • 启动 dev server

👉 项目越大,依赖越多,冷启动越慢

2.2 Vite 冷启动为什么快?

Vite 冷启动阶段几乎只做:

  • 启动一个轻量 HTTP server
  • 处理 index.html
  • 等浏览器来"点菜"

依赖预构建除外(下面说)

👉 所以你会看到:

  • 项目再大,启动时间也很稳定
  • 大多数项目 < 1s

2.3 依赖预构建(Vite 唯一一次"打包")

你可能会问:

"那 node_modules 里的依赖呢?它们不是 ESM 啊?"

答案是:esbuild

Vite 在首次启动时会:

  • 用 esbuild 把 node_modules 里的依赖
  • 转成 ESM
  • 合并成少量模块
  • 缓存到 .vite 目录

特点:

  • 只做一次
  • 极快(Go 写的)
  • 后续秒用缓存

👉 这一步解决的是:依赖多,但基本不改

3️⃣ HMR 实现:为什么 Vite 的热更新几乎"无感"?🔥

3.1 Webpack HMR 的本质

Webpack HMR:

  • 模块变更
  • 重新构建 chunk
  • 计算依赖边界
  • 推送更新
  • 执行替换逻辑

👉 chunk 是最小更新单位,粒度偏粗

3.2 Vite HMR 的本质

Vite HMR:

  • 基于原生 ESM 的模块级更新
  • 文件变了 → 精确到这个模块
  • 通过 WebSocket 通知浏览器
  • 浏览器重新请求这个模块

👉 模块 = HMR 最小单位

3.3 Vue SFC 的 HMR 为什么体验这么好?

Vue 插件帮你做了两件关键的事:

  • template 变 → 只重渲染 render
  • script 变 → 状态尽量保留
  • style 变 → 直接替换 CSS

所以你看到的效果是:

  • 页面不刷新
  • 状态不丢
  • 几乎"瞬间生效"

4️⃣ 插件机制:Vite 的灵魂不是快,是"可插拔"🔌

4.1 Vite 插件本质

Vite 插件 = 扩展 dev server 和 build 行为的钩子集合

Vite 插件:

  • 开发阶段:自己的一套插件钩子
  • 生产阶段:完全兼容 Rollup 插件

👉 这就是为什么生态能快速复用 Rollup 插件。

4.2 核心插件钩子(你要有感觉)

常见钩子:

  • resolveId:模块怎么被解析
  • load:模块内容从哪来
  • transform:代码怎么被改
  • handleHotUpdate:自定义 HMR 行为
  • configureServer:扩展 dev server
一个最小插件示意
ts 复制代码
export default function myPlugin() {
  return {
    name: 'my-plugin',
    transform(code, id) {
      if (id.endsWith('.ts')) {
        return code.replace('__DEV__', 'true')
      }
    }
  }
}

👉 插件能做的事:

  • 代码转换
  • 虚拟模块
  • 自动引入
  • 环境注入
  • 构建分析
  • Mock 数据

5️⃣ 与 Webpack 对比:不是"谁取代谁",而是"时代不同"⚖️

5.1 架构对比(核心差异)

维度 Vite Webpack
开发模式 原生 ESM 打包
冷启动 极快
HMR 粒度 模块级 chunk 级
配置复杂度
构建成熟度 高(Rollup) 非常高
生态 快速增长 极其成熟

5.2 Webpack 仍然有优势的场景

别神化 Vite,这些场景 Webpack 依然稳:

  • 老项目迁移成本极高
  • 深度定制 loader / runtime
  • 非 ESM 生态(历史包袱重)
  • 特殊构建链(微前端老方案)

5.3 Vue 项目中如何选择?

新项目:

  • Vue 3 + Vite = 默认最优解 ✅

老项目:

  • Vue 2 + Webpack → 不强求迁移
  • Vue 2 + Vite → 评估插件生态

6️⃣ Vue 项目实践建议(非常重要)🧩

6.1 正确使用 Vite 的姿势

  • 不要把 Webpack 思维直接搬过来
  • 少写"预打包思维"的配置
  • 相信按需加载

6.2 常见反模式

❌ 手动拆 chunk(开发阶段)

❌ 把所有插件都开着

❌ 在 dev 阶段做复杂优化

👉 Vite 的理念是:开发爽,生产稳

🧠 最后给你一个"工程师级总结"

  • Vite 快,不是因为"优化得好"
  • 而是因为:开发阶段根本没走"打包"这条路
  • Webpack 很强,但它是在"旧问题空间"里做到极致
  • Vite 是"换了一张地图"

如果你理解了这点,你就不会再纠结

👉 "Vite 到底比 Webpack 快多少"

而是会问:

👉 "我的项目是不是适合这种架构?"

相关推荐
jin1233227 分钟前
React Native鸿蒙跨平台剧本杀组队消息与快捷入口组件,包含消息列表展示、快捷入口管理、快捷操作触发和消息详情预览四大核心功能
javascript·react native·react.js·ecmascript·harmonyos
烬头88212 小时前
React Native鸿蒙跨平台实现二维码联系人APP(QRCodeContactApp)
javascript·react native·react.js·ecmascript·harmonyos
pas1362 小时前
40-mini-vue 实现三种联合类型
前端·javascript·vue.js
摇滚侠2 小时前
2 小时快速入门 ES6 基础视频教程
前端·ecmascript·es6
2601_949833392 小时前
flutter_for_openharmony口腔护理app实战+预约管理实现
android·javascript·flutter
珑墨2 小时前
【Turbo】使用介绍
前端
军军君013 小时前
Three.js基础功能学习十三:太阳系实例上
前端·javascript·vue.js·学习·3d·前端框架·three
xiaoqi9224 小时前
React Native鸿蒙跨平台如何实现分类页面组件通过searchQuery状态变量管理搜索输入,实现了分类的实时过滤功能
javascript·react native·react.js·ecmascript·harmonyos
打小就很皮...4 小时前
Tesseract.js OCR 中文识别
前端·react.js·ocr
qq_177767374 小时前
React Native鸿蒙跨平台实现应用介绍页,实现了应用信息卡片展示、特色功能网格布局、权限/联系信息陈列、评分展示、模态框详情交互等通用场景
javascript·react native·react.js·ecmascript·交互·harmonyos