为什么是Vite2
在Vite2官网文档中,有这么一段话:
然而,当我们开始构建越来越大型的应用时,需要处理的 JavaScript 代码量也呈指数级增长。大型项目包含数千个模块的情况并不少见。我们开始遇到性能瓶颈 —— 使用 JavaScript 开发的工具通常需要很长时间(甚至是几分钟!)才能启动开发服务器,即使使用 HMR,文件修改后的效果也需要几秒钟才能在浏览器中反映出来。如此循环往复,迟钝的反馈会极大地影响开发者的开发效率和幸福感。
这就是为什么是Vite2的原因。
与webpack 比较
Webpack的HMR
第一次冷启动慢的原因:
在之前的浏览器中没有模块化的设计,所以期望把所有源代码编译进一个 js 文件中提供给浏览器使用,所以在开发中当我们运行启动命令的时候,webpack 总是需要从入口文件去索引整个项目的文件,编译成一个或多个单独的 js 文件,即使采用了代码拆分,也需要一次生成所有路由下的编译后文件(这也是为什么代码拆分对开发模式性能没有帮助)。这也导致了服务启动时间随着项目复杂度而指数增长。
webpack-dev-server的热更新:
与本地服务器建立「socket」连接,注册 hash 和 ok 两个事件,发生文件修改时,给客户端推送 hash 事件。客户端根据 hash 事件中返回的参数来拉取更新后的文件。
HotModuleReplacementPlugin 会在文件修改后,生成两个文件,用于被客户端拉取使用。
在热更新上反映的就是部分代码变更, 整个模块的代码都需要重新编译,然后在推送更新。
Vite2的HMR
Vite 是基于 native ES module —— 浏览器厂商的不懈努力,现代浏览器基本已经全部支持了import/export 语法了。
在Vite中,启动服务器时,是不需要提交编译文件,而是在浏览器请求对应URL时,再提供文件,实施了真正的路由懒加载,这个比起Webpack就要节省了不少时间。
而在工程中不是所有的引用模块都是ES写法,可能是CommonJS 和 UMD 、AMD 等等,
这个时候Vite 会进行预构建,将其转换为ESM模块,以支持Vite。
并且将有许多内部模块的ESM依赖转换为单个模块,以提高后续页面加载性能。
对于JSX、或者TS 等需要编译的文件,Vite是用esbuild来进行编译的,不同与Webpack的整体编译,Vite是在浏览器请求时,才对文件进行编译,然后提供给浏览器。因为esbuild编译够快,这种每次页面加载都进行编译的其实是不会影响加速速度的。
esbuild
- 使用 Go 编写,并且编译成了机器码
- 大量使用并行算法
- esbuild 的所有内容都是从零编写的,避免了不要的数据转换
- 更有效利用内存