vite核心原理

Vite 在开发环境生产环境中采用了完全不同的打包策略,这是其高性能的核心设计之一。


🌐 1. 开发环境(Development):按需动态编译,不打包

✅ 核心机制:基于原生 ESM 的服务器

  • 不进行完整打包
  • 启动时仅启动一个轻量级 HTTP 服务器(基于 connect
  • 利用浏览器对 <script type="module"> 的原生支持,按需加载模块

🔧 工作流程:

  1. 浏览器请求 index.html
  2. HTML 中的 import /src/main.js 触发模块加载
  3. Vite 服务器拦截每个模块请求(如 /src/utils.js
  4. 动态编译该文件(例如:TS → JS、Vue → JS)
  5. 返回编译后的 JavaScript 内容

⚙️ 关键优化点:

步骤 技术实现
依赖预构建 使用 esbuildnode_modules 文件夹中原本不被浏览器直接支持的 CommonJS 或 UMD 格式的第三方库,自动转换成现代浏览器可以原生加载的 ES 模块(ESM)格式
按需转换 只有被访问的文件才编译,未使用的代码不会参与构建
HMR 热更新 通过 WebSocket 监听文件变化,精确替换模块,无需刷新页面

💡 举例:import _ from 'lodash' → 被重写为 /@modules/lodash.js → 由 esbuild 预构建后提供 ESM 版本

vite dev运行原理:

  1. 扫描你的代码中所有来自 node_modules 的导入(如 import _ from 'lodash'
  2. 收集需要预构建的依赖列表
  3. 使用 esbuild 将它们转换为 ESM 并打包成单个文件

HMR 热更新原理:

1. 启动服务器并建立 WebSocket 连接

  • Vite 开发服务器启动时,同时开启一个 WebSocket 服务(如 ws://localhost:24678
  • 浏览器通过注入的客户端脚本自动连接:
ini 复制代码
js
const ws = new WebSocket(`ws://localhost:${port}`);

2. 监听文件变化(使用 chokidar

  • 服务器监听项目根目录下的所有源码文件
  • 当你保存修改(如 src/utils.js),立即触发 change 事件

3. 分析模块依赖图谱

  • Vite 维护了模块之间的导入关系(Module Graph)
  • 知道哪些模块引用了被修改的文件
  • 例如:main.js → imports → utils.js,修改 utils.js 就会影响 main.js

4. 发送更新消息到浏览器

  • 服务器通过 WebSocket 推送更新通知:
json 复制代码
json
{
  "type": "update",
  "updates": [
    {
      "type": "js-update",
      "path": "/src/utils.js",
      "timestamp": 1734567890123
    }
  ]
}

5. 拉取最新模块代码

  • 浏览器接收到消息后,用时间戳作为缓存破坏参数,重新请求模块:
csharp 复制代码
js
await import('/src/utils.js?t=1734567890123');
  • 服务器返回编译后的最新 JavaScript 内容

6. 替换旧模块并更新视图

  • 执行新模块代码

  • 框架层处理更新:

    • Vue :通过 import.meta.hot.accept() 触发组件重新渲染
    • React:结合 Fast Refresh 保留状态并更新组件
    • CSS :替换 <style> 标签内容,无需重载页面

📦 2. 生产环境(Production):使用 Rollup 打包

虽然开发时不打包,但在生产环境中 Vite 会进行完整的打包优化

✅ 构建命令:

复制代码
bash
vite build

🛠️ 底层工具:Rollup

  • Vite 的生产构建是基于 Rollup 实现的
  • Rollup 更适合库和应用的静态分析与 tree-shaking
  • 支持代码分割、懒加载、CSS 提取等高级功能

📈 输出结果:

优化项 说明
Tree Shaking 删除未使用的代码
Code Splitting 自动拆分 chunk,支持动态导入
Minification 使用 Terser 压缩 JS,CSSNano 压缩 CSS
Asset Hashing 添加 content hash 实现缓存失效
Gzip/Brotli 预警 可配合插件生成压缩版本

🆚 对比总结

特性 开发环境(Dev) 生产环境(Build)
是否打包 ❌ 不打包 ✅ 完整打包
构建工具 esbuild(预构建依赖)+ 原生 ESM Rollup
启动速度 极快(毫秒级) 较慢(取决于项目大小)
模块处理 按需动态编译 全量静态分析
输出产物 无 bundle,直接服务源码 dist/ 目录包含优化后的静态资源
HMR 支持 ✅ WebSocket 实现热更新 ❌ 静态文件,不支持 HMR
适用场景 快速开发调试 部署上线

🧩 示例配置:vite.config.js

php 复制代码
js
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  plugins: [vue()],
  // 开发服务器配置
  server: {
    port: 3000,
    open: true
  },
  // 生产构建配置
  build: {
    outDir: 'dist',
    minify: 'terser',
    sourcemap: false,
    rollupOptions: {
      output: {
        chunkFileNames: 'assets/js/[name]-[hash].js',
        assetFileNames: 'assets/[ext]/[name]-[hash].[ext]'
      }
    }
  }
});

✅ 总结

  • 开发阶段:Vite 利用现代浏览器的 ESM 能力,做到"零打包",极大提升启动和热更新速度。
  • 生产阶段:切换到 Rollup 进行专业级打包,确保输出高度优化、体积小、性能好。
相关推荐
Gomiko7 分钟前
JavaScript DOM 原生部分(五):事件绑定
开发语言·前端·javascript
出来吧皮卡丘10 分钟前
A2UI:让 AI Agent 自主构建用户界面的新范式
前端·人工智能·aigc
Jeking21711 分钟前
进阶流程图绘制工具 Unione Flow Editor-- 击破样式痛点:全维度自定义解决方案
前端·流程图·workflow·unione flow·flow editor·unione cloud
晴转多云54311 分钟前
关于Vite后台项目的打包优化(首屏加载)
前端
阿苟15 分钟前
nginx部署踩坑
前端·后端
小林攻城狮17 分钟前
pdfmake 生成平铺式水印:核心方法与优化
前端
search720 分钟前
前端设计:CRG 2--CDC检查
前端·芯片设计
松涛和鸣23 分钟前
DAY33 Linux Thread Synchronization and Mutual Exclusion
linux·运维·服务器·前端·数据结构·哈希算法
逛逛GitHub30 分钟前
我把公众号文章导入了腾讯 ima,可以对话找开源项目了。
前端·github
lionliu051941 分钟前
JavaScript 变量声明最佳实践
前端·javascript·vue.js