Vite 核心原理
前置知识
ESm
ESM是JavaScript提出的官方标准化模块系统,不同于之前的CJS,AMD,CMD等等,ESM提供了更原生以及更动态的模块加载方案,最重要的就是它是浏览器原生支持的,也就是说我们可以直接在浏览器中去执行import,动态引入我们需要的模块,而不是把所有模块打包在一起。
Esbuild
Vite底层使用Esbuild实现对.ts、jsx、.
js代码文件的转化,所以先看下什么是es-build。 Esbuild是一个JavaScript`` Bundler 打包和压缩工具,它提供了与Webpack、Rollup等工具相似的资源打包能力。可以将JavaScript 和TypeScript代码打包分发在网页上运行。但其打包速度却是其他工具的10~100倍。
Rollup
Rollup是基于ESM的JavaScript打包工具。相比于其他打包工具如Webpack,他总是能打出更小、更快的包。因为 Rollup 基于 ESM 模块,比 Webpack 和 Browserify 使用的 CommonJS模块机制更高效。Rollup的亮点在于同一个地方,一次性加载。能针对源码进行 Tree Shaking(去除那些已被定义但没被使用的代码),以及 Scope Hoisting 以减小输出文件大小提升运行性能。
Rollup分为build(构建)
阶段和output generate(输出生成)
阶段。主要过程如下:
1. 获取入口文件的内容,包装成module,生成抽象语法树
2. 对入口文件抽象语法树进行依赖解析
3. 生成最终代码
4. 写入目标文件
1. 获取入口文件的内容,包装成module,生成抽象语法树
2. 对入口文件抽象语法树进行依赖解析
3. 生成最终代码
4. 写入目标文件
基于 ES 模块导入
Vite利用了原生的ES模块(ESM)来管理和加载模块。与传统的打包工具(如 webpack)不同,Vite 不需要在开发环境中预先打包整个应用。相反,它直接在浏览器中利用<script type='module'>
标签加载模块,这大大减少了启动时间。
按需编译
在传统的打包工具中,即使只修改了一个小的模块,整个应用也需要重新打包和重新加载,这会花费相当的时间。
Vite 通过分析源代码中的 import 语句,将其转换为浏览器可以直接运行的代码。这种按需编译的方式,使得 Vite 只需要编译少量的代码,从而实现了更快的冷启动和热更新。
使用 Rollup 插件
Vite 在生产环境下使用 Rollup 作为其打包工具。Rollup 本身是一个高效的模块打包器,它支持代码分割和懒加载等特性。Vite 能够复用 Rollup 的插件生态系统,这意味着开发者可以利用众多现成的插件来扩展其项目的功能。
快速的热模块替换(HMR)
Vite 提供了高效的热模块替换(Hot Module Replacement,HMR)。HMR 允许在应用运行时替换、添加或删除模块,而无需完全刷新页面。这不仅加快了开发中的迭代速度,还保持了应用的状态,从而提高了开发效率。
预打包依赖
Vite 会在第一次启动时预打包(pre-bundle)项目的依赖。这是通过 Esbuild 完成的,它是一个非常快速的 JavaScript 打包工具。这样做的目的是优化浏览器加载大量的 ESM 模块所需的时间。一旦依赖被预打包,它们会被缓存下来,进一步提高了后续启动的速度。
高效的缓存策略
Vite 使用强缓存策略来缓存未改变的模块。这意味着一旦模块被编译,它就会被缓存,除非该模块或其依赖发生改变。这样可以确保重复请求相同模块时的高效加载。
总结
- 基于ESM 的 HMR 热更新
- 基于esbuild的依赖预编译优化