初识vite

初识vite

为什么选 Vite

现实问题

在浏览器支持 ES 模块之前,开发者没有一种可以利用的原生机制来以模块化方式编写 JavaScript。这也是我们为什么有了 “打包” 这个概念的原因:使用工具抓取、处理和链接我们的源代码模块到文件中,使其可以运行在浏览器中。

在过去我们已经见过诸如 webpack,Rollup 和 Parcel ,它们都大大改进了前端开发者的开发体验。

然而,随着我们开始构建越来越多的雄心勃勃的应用程序,我们处理的 JavaScript 数量也呈指数级增长。大型项目包含数千个模块的情况并不少见。我们开始遇到基于 JavaScript 的工具的性能瓶颈:通常需要很长时间(有时甚至是几分钟!)才能启动开发服务器,即使使用 HMR,文件编辑也需要几秒钟才能在浏览器中反映出来。缓慢的反馈会极大地影响开发人员的生产力和幸福感。

Vite 旨在利用下面这些生态系统中的新进展解决上述问题:浏览器支持原生模块,越来越多 JavaScript 工具使用编译型语言编写。

缓慢的服务器启动

当冷启动开发服务器时,基于打包器的方式是在提供服务前去急切地抓取和构建你的整个应用。
Vite 通过在一开始将应用中的模块区分为两类:依赖 和 源代码,改进了开发服务器启动时间。

依赖:大多为纯 JavaScript 并在开发时不会变动。一些较大的依赖(例如有上百个模块的组件库)处理的代价也很高。依赖也通常会以某些方式(例如 ESM 或者 CommonJS)被拆分到大量小模块中。

Vite 将会使用 esbuild 预构建依赖。Esbuild 使用 Go 编写,并且比以 JavaScript 编写的打包器预构建依赖快 10-100 倍。

源代码:通常包含一些并非直接是 JavaScript 的文件,需要转换(例如 JSX,CSS 或者 Vue/Svelte 组件),时常会被编辑。同时,并不是所有的源代码都需要同时被加载。(例如基于路由拆分的代码模块)

Vite 以 原生 ESM 方式服务源代码。这实际上是让浏览器接管了打包程序的部分工作:Vite 只需要在浏览器请求源代码时进行转换并按需提供源代码。根据情景动态导入的代码,即只在当前屏幕上实际使用时才会被处理。

初识vite

初识vite

缓慢的更新

当基于打包器启动时,编辑文件后将重新构建文件本身。很显然我们不应该重新构建整个包,因为这样更新速度会随着应用体积增长而直线下降。

一些打包器的开发服务器将构建内容存入内存,这样它们只需要在文件更改时使模块图的一部分失活[1],但它也仍需要整个重新构建并重载页面。这样代价很高,并且重新加载页面会消除应用程序的当前状态,所以打包器支持了动态模块热重载(HMR):允许一个模块 “热替换” 它自己,而对页面其余部分没有影响。这大大改进了开发体验 - 然而,在实践中我们发现,即使是 HMR 更新速度也会随着应用程序规模的增长而显著下降。

在 Vite 中,HMR 是在原生 ESM 上执行的。当编辑一个文件时,Vite 只需要精确地使已编辑的模块与其最近的 HMR 边界之间的链失效(大多数时候只需要模块本身),使 HMR 更新始终快速,无论应用程序的大小。

Vite 同时利用 HTTP 头来加速整个页面的加载(再次让浏览器为我们做更多事情):源代码模块的请求会根据是否更改,利用 304 Not Modified 协商缓存,而依赖模块请求则会通过 Cache-Control: max-age=31536000,immutable 协商缓存,因此一旦被缓存它们将不会再次请求。

为什么生产环境仍需打包

尽管原生 ESM 现在得到了广泛支持,但由于嵌套导入会导致额外的网络往返,在生产环境中发布未打包的 ESM 仍然效率低下(即使使用 HTTP/2)。为了在生产环境中获得最佳的加载性能,最好还是将代码进行 tree-shaking、懒加载和 chunk 分割(以获得更好的缓存)

要确保开发服务器和产品构建之间的最佳输出和行为一致并不容易。所以 Vite 附带了一套 预配置、预优化 的 构建命令,开箱即用。

上一篇:一看就懂的,java深拷贝浅拷贝


下一篇:微信小程序开发教程-手势解锁