Vite

Vite

Vite(法语 “快速 “的意思,发音为/vit/)是一个新品种的前端构建工具,能显著提升前端开发体验。它由两大部分组成。

  • 一个通过原生 ES 模块为您的源文件提供服务的开发服务器,具有丰富的内置功能和惊人的快速热模块替换(HMR)。
  • 一个使用 Rollup 进行代码打包的命令,预先配置为生产输出高度优化的静态资产。

如今,大多数 JavaScript 开发人员都熟悉以下 ES 模块语法。

import { foo } from "./other-module";

这种语法已经在各大浏览器中得到了广泛的本地支持。然而,在浏览器对 ES 模块有原生支持之前,我们不得不依靠捆绑程序(Browserify、webpack、Parcel 或 Rollup)将所有模块的源代码合并到一个文件中,这样即使在开发过程中也能被浏览器提供服务。在开发过程中,捆绑有两个缺点。

  • 服务器启动慢。当启动开发服务器时,bundler 总是急切地抓取你的整个应用程序,即使有代码分割点存在。例如,在一个有十几条路由的应用中,每条路由都是懒加载的,你仍然需要等待捆绑器处理你应用中的每一个文件,然后才能开始处理单个路由页面。在服务器启动时不需要做任何准备工作,Vite 只需在浏览器发出请求时按需编译并提供文件。在代码分离的应用中,只有当前路由页面使用的模块需要被服务。

Vite 架构变化示意

  • 更新速度慢。当一个文件被编辑时,除了重新构建文件本身外,捆绑器还需要使其部分模块图无效,并重新构建整个捆绑。这意味着随着你的应用规模的增长,从保存文件到看到浏览器中反映的变化之间的反馈速度会线性恶化。在大型应用程序中,即使启用了热模块替换,这个捆绑重新构建步骤也会变得非常昂贵。Vite 是如何解决的。每一个被服务的文件都会通过 HTTP 头文件进行缓存(只要有可能就会有 304 未修改),如果浏览器缓存被禁用,则通过 Vite 的内存缓存。在文件编辑上,我们只是将该文件的缓存无效化。此外,在原生 ESM 上的热模块替换只需要精确地重新获取无效的模块,这使得无论您的应用程序的大小,它都会持续快速。

即使现在广泛支持原生 ESM,但由于嵌套导入导致的额外网络往返,在生产中运送未捆绑的 ESM 仍然效率低下(即使是 HTTP/2)。要想在生产中获得最佳的加载性能,最好还是将你的代码与树形震荡、懒加载和常见的分块(为了更好的缓存)捆绑在一起。确保开发服务器和生产构建之间的最佳输出和行为一致性并不容易。这就是为什么 Vite 提供了一个预配置的构建命令,可以在开箱即用。

Vite 遗留问题

笔者在项目中尝试用 Vite 后,发现仍存在以下问题:

  • 对于 node_modules 中的 Less 系列支持不友好,不能兼容组件使用 Less 的场景