vite工作原理是什么
-
开发环节
- 当启动vite开发服务器(基于koa)时,vite会检测项目中的入口文件(例如:index.html),初始化配置,监听端口(默认3000)
- 当在浏览器中访问
index.html时,服务器直接返回HTML文件。浏览器解析到<script type="module">标签后发起JS模块请求 - vite使用浏览器内置的es模块系统(esm)加载需要的模块,这是浏览器原生支持的一种模块加载方式
- vite会在浏览器中运行一个开发服务器,通过代理的形式将模块请求重定向到实际的模块文件路径上,不需要像webpack一样先打包再推送到浏览器
- 普通文件(如.js):直接返回源码
- 特殊文件(如.vue,.ts):实时编译为浏览器可执行的js格式,通过
Content-Type: text/javascript返回 - 裸模块 (如
import vue from 'vue'):路径被重写为/@modules/vue.js,服务器从node_modules预构建的依赖中返回
- 依赖预构件(关键优化)
- 当执行vite或vite dev命令启动开发服务器时,vite会立即执行依赖预构建流程,这个过程是在浏览器访问页面之前完成,
- 非按需编译,与业务代码的按需编译不同,第三方依赖的预构建是一次性批量处理的,不会延迟到浏览器请求时才完成
- 启动时用
esbuild将第三方依赖(如lodash)转换为ESM格式并合并为单文件,减少HTTP请求。 - 结果缓存到
node_modules/.vite,后续启动直接复用
- 热更新
- 当代码中有修改时,vite会根据代码的依赖关系对只有发生变化的模块进行重新构建,并将变化通过WebSocket通知浏览器实现热更新,无需刷新页面
-
生产环节
- 依赖分析和代码拆分
- 在生产环境中,vite会使用rollup解析入口文件,构建完整依赖关系图;根据动态导入(如路由懒加载)或配置规则拆分生成多个按需加载的chunk,例如路由组件拆分成独立chunk;
- 模块优化和合并
- 使用treeshaking剔除无用代码;将第三方库(如react,lodash)合并到vendor.js,减少重复请求;将js/css代码压缩,静态资源(图片等)添加哈希指纹
- 缓存机制
- 每个chunk文件生成唯一哈希文件名,浏览器可长期存储,代码修改后仅影响相关chunk的hash值,未改动chunk的缓存保持不变
- 依赖分析和代码拆分
-
不同环境差异对比
| 场景 | 开发环境 | 生产环境 |
|---|---|---|
| 模块加载 | 每个模块独立请求 | 合并为chunk文件 |
| 缓存单位 | 单个模块 | 整个chunk文件 |
| 构建工具 | esbuild(转换单个模块) | rollup(打包合并) |
| 热跟新 | 模块机热跟新(毫秒级) | 不适用(需重新构建) |