vite学习笔记

3 阅读4分钟

同时构建工具, 为什么vite能兴起,就是因为快。

介绍

新一代的前端构建工具,能够显著的提升前端开发体验 , 由两部分组成:

  • 一个开发服务器,基于ES Module
  • 一个构建指令,使用Rollup打包

特点:

  • 基于ESM,跳过打包阶段,冷启动更快
  • 基于ESM,热更新更快,利用浏览器缓存,更新更快,
  • 基于ESM的方式提供源码,真正的按需加载

为什么

当开始构建越来越大的项目时,基于js的开发工具效率会越来越低, 启动项目的时间越来越长,即使使用HMR,文件修改之后,也需要几秒才能反馈到页面上,开发体验上不友好。

缓慢的服务器启动

webpack必须构建整个应用才能启动项目, vite通过将项目中的模块分为源码和依赖两部分,改进了服务器启动时间。

  • 依赖:大多数为开发时不会变动的纯代码,一个较大的依赖处理起来代价也很高,vite使用esBuild进行预构建依赖,速度更快
  • 源码:vite只需要在浏览器请求源码时进行转换(JSX CSS)并按需提供源码,只有在当前屏幕上实际使用才会被处理。

缓慢的更新

基于打包的项目启动时,当源代码修改后,要重新构建整个项目,效率变低。

一些打包器将构建的内容存放在内存中,更新之后替换修改的内容,但是也是要重新构建加载页面。并且重新加载之后,项目的状态也会丢失, 所以使用了HMR热替换,但是实践中发现,随着项目的规模变大,HMR速度也是越来越慢。(webpack编译,请求变更后的模块代码,)

在vite中,HMR时基于原声ESM实现,仅更新修改的模块, 并且在缓存方面, 源码模块使用协商缓存,依赖方面使用强缓存加速整个页面的加载速度。

原理

vite的核心原理是利用浏览器ES6的import,碰见import就会发起请求加载文件, vite启动了一个服务器,对请求进行拦截,遍历ast,找到文件进行编译,返回ESM的形式交给浏览器。整个过程中没有对文件进行打包编译,所以速度更快。

基于ESM的冷启动

webpack是从入口出发,解析依赖,打包构建,等所有模块构建完成之后,再启动dev server。当一个模块修改之后,整个项目会被重新打包,效率变低。

vite使用ESM, 先启动服务器,当遇到import时,就会下载对应的模块,实现了动态加载。 项目变大路由变多,并不影响启动速度。

基于ESM的热更新

目前大多数的打包工具,都是基于websocket创建浏览器和服务器之间的通信,监听文件,当文件被修改之后,服务器通知浏览器对文件进行更新替换。

webpack:重新编译,更新变更的模块,客户端重新加载。

vite:将相关的模块与临近的HMR边界链接失效,对发生变更的模块重新加载,不会随着项目的规模变大而时间变长。

依赖预构建

首次启动vite时,会进行依赖预构建,目的:

  • 兼容CommonJS和UMD; vite开发服务器是将所有模块识别为ESM,所以vite必须将commonJS和UMD编写的模块转换成ESM模块。
  • 减少模块请求,性能优化; vite将具有许多内部模块的ESM依赖转换为单个模块。

当依赖的锁文件变化,或者config等配置发生变化时会重新预构建。 会重新生成hash值,用于浏览器的强缓存

基于Esbuild:使用编译型,多进程go语言,比js实现的打包工具更快。

参考

深入理解Vite核心原理

Vite 的实现原理,确实很巧妙

vite官方文档