同时构建工具, 为什么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实现的打包工具更快。