前言
近几年,Vite 已经逐渐成为 Vue、React 等现代前端项目的默认选择。
很多开发者第一次体验 Vite 时,最大的感受只有一个:
快。
一个大型项目:
Webpack:
启动几十秒。
Vite:
几秒钟。
甚至:
瞬间启动。
很多人认为:
只是:
Rollup 更快。
实际上:
真正的原因远比这复杂。
本文从底层原理分析:
为什么 Vite 能够明显快于传统 Webpack。
Webpack 为什么慢?
Webpack:
属于:
Bundle First。
也就是说:
启动之前。
必须:
分析:
整个项目。
例如:
入口文件
↓
依赖分析
↓
Loader
↓
Plugin
↓
打包
↓
启动 Dev Server
即使:
只修改:
一个按钮。
Webpack:
仍然需要:
维护整个依赖图。
因此:
项目越大。
启动越慢。
Vite 的设计思想
Vite:
反过来。
它认为:
开发阶段:
没有必要:
提前打包。
因此:
采用:
Native ES Module。
浏览器:
直接加载模块。
例如:
App.vue
↓
浏览器请求
↓
按需加载
真正做到:
需要哪个模块。
就编译哪个模块。
为什么浏览器可以直接加载?
现代浏览器已经支持:
<script type="module">
浏览器:
天然支持:
ES Module。
因此:
Vite:
不需要:
开发阶段:
重新实现模块系统。
而是:
利用浏览器能力。
这也是:
Vite 能够秒启动的重要原因。
预构建(Pre-bundling)
虽然:
源码:
按需编译。
但是:
第三方依赖:
例如:
vue
react
lodash
仍然很多。
如果:
浏览器:
逐个加载。
请求数量会非常大。
因此:
Vite:
第一次启动。
会使用:
esbuild。
预构建:
node_modules。
之后:
缓存。
下一次:
几乎不用重新处理。
esbuild 为什么快?
Webpack:
主要基于:
JavaScript。
而:
esbuild:
使用:
Go。
编译速度:
远高于传统 JS 工具。
因此:
依赖预构建:
几乎瞬间完成。
热更新(HMR)
Webpack:
通常:
更新:
整个模块树。
Vite:
只更新:
真正发生变化的模块。
例如:
修改:
Button.vue
浏览器:
只重新请求:
Button。
而不是:
整个应用。
因此:
热更新:
几乎:
毫秒级。
Rollup 在哪里?
很多人误解:
Vite:
一直使用 Rollup。
实际上:
开发阶段:
几乎不用 Rollup。
真正:
生产构建:
才交给:
Rollup。
因此:
开发体验。
生产优化。
两者兼得。
Plugin 机制
Vite Plugin:
实际上:
继承了:
Rollup Plugin。
因此:
生态迁移成本:
很低。
很多 Rollup 插件:
稍作修改。
即可用于:
Vite。
Vite 是否一定更快?
并不是。
如果:
项目:
极小。
Webpack:
差距:
并不明显。
但:
随着:
项目:
越来越大。
模块:
越来越多。
Vite 的优势会越来越明显。
Vite 的局限
Vite:
依赖:
现代浏览器。
对于:
非常旧的浏览器。
需要:
额外兼容。
另外:
一些非常复杂的企业级插件。
迁移:
也需要一定成本。
因此:
迁移之前:
仍然建议充分测试。
总结
Vite 的成功,并不仅仅因为速度快。
更重要的是:
它重新思考了开发阶段和生产阶段的构建方式。
开发时:
按需编译。
生产时:
完整打包。
这种设计既提升了开发效率,又保留了成熟构建工具的能力。
随着浏览器对 ES Module 的支持越来越完善,这种设计思想也正在成为现代前端工具的发展方向。
X记录空间