← 返回目录

第 19 卷

第 19 / 26 卷日期:

@vitejs/plugin-vue、 @vitejs/plugin-react),核心原因是:不同框架的组件渲染机制、状态管理方式不同,需要针对性的适配逻辑。

以 Vue 3 为例, @vitejs/plugin-vue 的 HMR 适配逻辑:

  • 监听 Vue 组件文件变化,编译生成新的组件渲染函数。
  • 通过 Vue 3 的 app.config.globalProperties 暴露的 HMR 接口,替换组件的定义。
  • 触发组件的重新渲染,保留组件内部的响应式状态(如 ref、 reactive 定义的状态)。
  1. Vite HMR 优势总结
  • 速度快:基于原生 ESM 直接替换模块,无需处理依赖链,更新速度恒定,不受项目大小影响。
  • 状态保留好:配合框架插件,可精准保留组件状态、响应式数据,开发体验极佳。
  • 轻量化:无需像 Webpack 那样生成增量 bundle,仅需编译变化模块,性能损耗小。
  • 自动适配:主流框架(Vue、React、Svelte)的插件已内置 HMR 逻辑,零配置即可使用。

二十四、Vite如何优化依赖预构建过程?

依赖预构建是 Vite 开发环境的核心优化手段之一,核心目标是“解决第三方依赖的兼容性和加载性能问题”。具体来说,Vite 会将 CommonJS 格式的第三方依赖(如 lodash)转换为 ESM 格式,同时

将多个小模块合并为单个模块(减少浏览器请求数量),并缓存预构建结果。Vite 通过“智能缓存、按需预构建、并行处理”等机制,进一步优化依赖预构建过程,确保开发环境的启动速度和加载性

能。

  1. 依赖预构建的核心目标(为何需要预构建)

第三方依赖(如 node_modules 中的包)通常存在以下问题,影响开发环境的加载效率:

• 模块格式不兼容:多数第三方依赖是 CommonJS 格式(如 lodash、moment),而 Vite 开发环

境基于原生 ESM,浏览器无法直接解析 CommonJS 模块,需实时转换,性能损耗大。

• 大量小模块导致网络瀑布:部分依赖(如 React 生态、lodash-es)包含大量小模块(单个功能一

个文件),浏览器加载时会发起数百次并发请求,产生“网络瀑布”,加载速度慢。

• 依赖路径复杂:第三方依赖内部的路径引用可能包含别名、条件导入等,直接加载会导致解析失

败。

依赖预构建正是为了解决以上问题,通过提前处理第三方依赖,提升开发环境的加载效率。

  1. Vite 优化依赖预构建的核心机制

Vite 从“缓存复用、构建策略、处理效率”三个维度优化依赖预构建过程,具体机制如下:

• 缓存存储位置:预构建结果缓存到项目根目录的 node_modules/.vite 文件夹中,包含转换

后的 ESM 模块、合并后的包、缓存元信息( _metadata.json)。

• 缓存失效条件:仅当以下条件发生变化时,才会重新预构建,否则直接复用缓存:依赖版本变化

(如 lodash 从 4.17.0 升级到 4.17.21)。

  • Vite 配置变化(如 optimizeDeps 选项修改)。
  • 项目根目录的 package.json 中 dependencies 或 devDependencies 变化。
  • 缓存文件被手动删除。

强制预构建:若需要强制重新预构建,可执行 vite optimize 命令,或删除 node_modules/.vite 文件夹。

(2)按需预构建:仅处理必要依赖

Vite 不会预构建所有第三方依赖,而是通过“入口扫描”识别“必要依赖”,仅对这些依赖进行预构建,减少构建工作量。

• 必要依赖识别:Vite 会扫描项目的入口模块(如 src/main.js)及其直接/间接依赖,识别出需

要预构建的第三方依赖(如 vue、 axios、 lodash)。

• 自定义预构建范围:通过 vite.config.js 的 optimizeDeps.include 和

optimizeDeps.exclude 选项,手动指定需要预构建或排除的依赖: // vite.config.js

import { defineConfig } from 'vite';

export default defineConfig({ optimizeDeps: {

include: ['lodash-es', 'date-fns'], // 强制预构建指定依赖 exclude: ['jquery'] // 排除不需要预构建的依赖(如已是 ESM 格式)

} });

(3)并行处理:提升预构建速度

Vite 在预构建过程中,通过多线程并行处理多个依赖的转换和合并,充分利用 CPU 资源,减少预构建耗时。

• Vite 内部使用 esbuild(基于 Go 语言的构建工具)进行依赖预构建, esbuild 本身支持并

行处理,速度远超传统的 JavaScript 构建工具(如 Babel)。

• 对于多个独立的第三方依赖(如 vue 和 axios),Vite 会并行触发 esbuild 处理,避免串

布”问题。

• 例如: lodash-es 包含数百个小模块(如 lodash-es/map.js、 lodash-

es/filter.js),Vite 会将其合并为一个 lodash-es.js 预构建包,浏览器仅需发起一次请求即可加载所有 lodash-es 模块。

• 合并策略:Vite 会根据依赖的内部依赖关系,智能合并关联紧密的模块,避免合并后的包体积过

大。

(5)esbuild 加速:高效的转换工具

Vite 依赖预构建的核心工具是 esbuild,而非传统的 JavaScript 工具(如 Rollup、Babel), esbuild 的特性直接提升了预构建效率:

  • 速度快:基于 Go 语言开发,编译速度是 Babel 的 10-100 倍。

• 多格式支持:原生支持 CommonJS → ESM 的转换、JSX 转译、TypeScript 转译等,无需额外配

置。

  • 内置优化:支持代码压缩、模块合并等优化,一站式完成预构建需求。
  1. 依赖预构建的流程(优化后)
  2. 启动 Vite 项目时,首先检查 node_modules/.vite 缓存是否存在,且缓存是否有效(根据缓

存元信息判断)。

  1. 若缓存有效,直接复用缓存的预构建结果,跳过预构建过程,项目秒级启动。
  2. 若缓存失效,执行以下预构建步骤:扫描项目入口模块及其依赖,识别需要预构建的第三方依赖。
  3. 使用 esbuild 并行处理这些依赖:将 CommonJS 转换为 ESM,合并小模块为预构建包。
  4. 将预构建结果写入 node_modules/.vite 文件夹,同时生成缓存元信息。
  5. 开发环境加载第三方依赖时,直接加载 node_modules/.vite 中预构建后的 ESM 模块,提升

加载速度。

  1. 特殊场景的预构建优化

(1)Monorepo 项目

对于 Monorepo 项目(多包管理),Vite 通过 optimizeDeps.link 选项,将本地包链接到预构建流程中,避免重复预构建本地依赖:

Code block

1// vite.config.js

全站分卷索引 · 26 卷
  1. 1第 1 卷
  2. 2第 2 卷
  3. 3第 3 卷
  4. 4第 4 卷
  5. 5第 5 卷
  6. 6第 6 卷
  7. 7第 7 卷
  8. 8第 8 卷
  9. 9第 9 卷
  10. 10第 10 卷
  11. 11第 11 卷
  12. 12第 12 卷
  13. 13第 13 卷
  14. 14第 14 卷
  15. 15第 15 卷
  16. 16第 16 卷
  17. 17第 17 卷
  18. 18第 18 卷
  19. 19第 19 卷
  20. 20第 20 卷
  21. 21第 21 卷
  22. 22第 22 卷
  23. 23第 23 卷
  24. 24第 24 卷
  25. 25第 25 卷
  26. 26第 26 卷