开发模式服务器启动
开发环境中,Webpack
是先打包再启动开发服务器,而 Vite
则是直接启动,然后再按需编译依赖文件。
- 使用
Webpack
时,所有的模块都需要在开发前进行打包成一个或者多个 bundle,增加启动时间和构建时间。 Vite
在请求模块时再进行实时编译,这种按需动态编译的模式极大地缩短了编译时间,特别是在大型项目中,Vite
的优势更为明显。(应用中的模块区分为 依赖(node_modules) 和 源码(项目代码) 两类)
ESM 的支持
现代浏览器本身就支持 ESM,会主动请求获取文件,Vite 将开发环境下的模块文件直接作为浏览器要执行的文件。减少了 Webpack 将打包后的文件交给浏览器执行的过程。也正是因为 ESM 支持,使得 Vite 可以在开发模式服务器启动中,使用按需动态编译的模式编译依赖文件。
默认情况下,模块会延迟加载,执行时机在文档解析之后,触发DOMContentLoaded事件前。
底层语言的差异
- Vite 使用 esbuild 预构建依赖。Esbuild 使用 Go 编写,比以 Node.js 编写的打包器预构建依赖快 10-100 倍。
- Webpack 是基于
Node.js
构建。
预构建依赖通常指的是在项目
启动或构建
之前,对项目中所需的依赖项进行预先的处理或构建
。这样做的好处在于,当项目实际运行时,可以直接使用
这些已经预构建好的依赖,而无需再进行实时的编译或构建,从而提高了应用程序的运行速度和效率。
热更新
- 在 Webpack 中,当一个模块或其依赖的模块内容改变时,需要
重新编译
这些模块。 - 在 Vite 中,当某个模块内容改变时,只需要让浏览器
重新请求
该模块即可,这大大减少了热更新的时间。
热更新的出现:一般打包器中,当一个模块或其依赖的模块内容改变时,需要
重新编译
这些模块。显然我们不应该重新构建整个包,因为这样更新速度会随着应用体积增长而直线下降。一些打包器的开发服务器将构建内容存入内存,这样它们只需要在文件更改时使模块图的一部分失活,但它也仍需要整个重新构建并重载页面。这样代价很高,并且重新加载页面会消除应用的当前状态,所以打包器支持了动态模块热重载(HMR):允许一个模块 "热替换" 它自己,而对页面其余部分没有影响。这大大改进了开发体验 - 然而,在实践中我们发现,即使是 HMR 更新速度也会随着应用规模的增长而显著下降。
- 在 Vite 中,HMR 是在原生 ESM 上执行的,非常快。当编辑一个文件时,Vite 只需要精确地使已编辑的模块与其最近的 HMR 边界之间的链失效(大多数时候只需要模块本身),使 HMR 更新始终快速,无论应用的大小。
- Vite 同时利用 HTTP 头来加速整个页面的重新加载(再次让浏览器为我们做更多事情):源码模块的请求会根据 304 Not Modified 进行协商缓存,而依赖模块请求则会通过 Cache-Control: max-age=31536000,immutable 进行强缓存,因此一旦被缓存它们将不需要再次请求。
生态
- wepback 生态丰富、社区资源丰富,有大量可以使用的 loader 和 plugin,可高度配置。
- 配置较为复杂。而 vite 开箱即用,配置简单。
开发环境
- 使用 rollup是因为 esbuild对于 css 处理和代码分割不是很友好。
- 不过目前尤大团队正在开发 rolldown,以便同时管理预构建和打包,取代 esbuild + rollup。