# 双引擎架构

Vite 的双引擎架构指的是在构建工具中同时使用 EsbuildRollup 两个现代构建引擎。这种架构使得 Vite 在开发阶段能够提供极快的热重载(HMR)和冷启动速度,同时在生产环境下生成优化的静态资源。

vite架构图

# 开发阶段

在开发阶段,Rollup 并没有参与核心的依赖预构建过程。Vite 直接使用 Esbuild 处理预构建,Esbuild 将依赖预构建为浏览器原生的 ES Modules (opens new window)ES Modules允许浏览器直接加载并执行模块,而不需要通过打包步骤。这极大地加快了开发时的热更新速度。

# 开发构建流程概览

  • 插件处理:Vite 首先会加载并应用类似 Rollup 的插件,处理各种资源文件(CSS、图像、JavaScript、TypeScript 等),插件机制在这一阶段负责文件的转换与处理。
  • 依赖预构建:处理完插件之后,Vite 使用 Esbuild 对第三方依赖库进行预构建,以便快速加载依赖模块。
  • 浏览器请求:浏览器在开发时通过 ES 模块按需加载应用代码和预构建的依赖库。

TIP

Vite 在开发环境中通过 Vite 自己的机制来处理插件相关的逻辑,但并不是 Rollup 引擎在真正运行。Vite 通过自己定制的开发服务器对这些插件进行了适配。

开发环境中,Esbuild 主要处理以下任务:

  • 快速解析并转换代码,如处理 TypeScriptJSX 等文件。
  • 直接利用浏览器的 ES 模块支持,避免模块打包和转译的开销,最大化启动和响应速度。

# 生产环境中的构建工具

在生产环境中,Esbuild 并不直接参与构建流程,Vite 主要依赖 Rollup 进行生产环境的打包和优化。因为 ES Modules 的按需加载虽然在开发时表现出色,但在生产环境中,如果模块过多,浏览器需要频繁请求,可能会影响性能。因此 Vite 的生产模式选择了 Rollup 进行优化打包,生成高度优化的静态资源包。

# 生产构建流程概览

  1. Rollup 构建和优化

    • Vite 使用 Rollup 作为打包引擎,在生产构建时,它会处理项目的所有依赖关系、模块分割、代码压缩等优化操作。
    • Rollup 具备强大的 tree-shaking 功能,能够删除未使用的代码,从而减小打包后的文件大小。
    • Rollup 会处理所有的静态资源(如 CSS、图像、字体等),并根据配置进行相应的打包和优化。
    • Rollup 的插件生态也可以在生产环境中被充分利用,比如常见的代码压缩、懒加载和其他性能优化。
  2. 代码分割和动态导入

    • Rollup 在生产构建中可以进行 代码分割(code splitting),将应用的不同部分拆分成多个模块,以支持按需加载(lazy loading)。
    • 动态导入的代码也会在生产时被优化成独立的 chunk,以提升应用的加载速度和性能。
  3. 资源处理

    • 所有的资源文件(如 CSS、图像等)在生产环境下通过 Rollup 处理,并根据配置生成优化后的产物。Rollup 的插件系统能根据需要进行压缩、缓存和版本管理。

开发环境中,Rollup 主要处理以下任务:

  • 插件机制:开发者可以使用 Rollup 的插件(如 @rollup/plugin-replace、@rollup/plugin-alias 等)来处理资源或代码转换。
  • Rollup 打包Vite 利用 Rollup 的优势,对代码进行树摇 (tree-shaking),减少无用代码,并且将所有模块打包成更少的文件,降低浏览器请求次数。
  • 代码拆分 (Code Splitting)Rollup 也支持按需加载,可以根据路由或者页面模块进行动态加载,从而优化首屏加载速度和整体性能。
  • 静态资源处理Vite 会在生产打包时自动优化、压缩静态资源如 CSS、图片、字体等,进一步提升生产环境的性能。

# Vite 双引擎架构的优势

# 1. 极快的冷启动

传统构建工具 (如 Webpack) 在启动开发服务器时,通常需要进行一次完整的打包,特别是在大型项目中,冷启动时间可能会很长。而 Vite 通过直接利用 ESModules,避免了冷启动时的打包过程,因此启动速度极快。

# 2. 模块热更新 (HMR) 更高效

Vite 只更新修改的模块,而不是重新打包和加载整个应用程序,这大大减少了开发过程中的等待时间。由于 HMR 的基础是 ESModules,Vite 能够精确地知道哪些模块需要重新编译,哪些可以保持不变。

# 3. 按需编译

Vite 的按需编译机制避免了整个项目的打包,只有在请求时才会编译模块。因此,无论项目多大,初次加载的速度都很快。而且因为是模块化请求,用户仅在需要时才会加载某些依赖,避免了不必要的资源浪费。

# 4. 生产环境的高效打包

生产环境下,Vite 通过 Rollup 进行打包,利用 Rollup 强大的树摇和代码拆分功能,使得最终生成的代码包尽可能小。这保证了生产环境中的加载速度和性能。