Skip to content

vite预构建过程及原理

原理

通过index.html入口文件解析 js/ts 依赖项,并根据js/ts中的import/require等语法进行依赖收集,区分出哪些是第三方模块,哪些是当前项目的模块,对第三方模块进行缓存与合并,以减少http的请求次数。

为什么需要预构建-原因

  1. CommonJS 和 UMD 兼容性: 在开发阶段中,Vite 的开发服务器将所有代码视为原生 ES 模块。因此,Vite 必须先将以 CommonJS 或 UMD 形式提供的依赖项转换为 ES 模块。在转换 CommonJS 依赖项时,Vite 会进行智能导入分析,这样即使模块的导出是动态分配的(例如 React),具名导入(named imports)也能正常工作:
js
// 符合预期
import React, { useState } from 'react'
  1. 性能: 为了提高后续页面的加载性能,Vite将那些具有许多内部模块的 ESM 依赖项转换为单个模块。

有些包将它们的 ES 模块构建为许多单独的文件,彼此导入。例如,lodash-es 有超过 600 个内置模块!当我们执行 import { debounce } from 'lodash-es' 时,浏览器同时发出 600 多个 HTTP 请求!即使服务器能够轻松处理它们,但大量请求会导致浏览器端的网络拥塞,使页面加载变得明显缓慢。 通过将 lodash-es 预构建成单个模块,现在我们只需要一个HTTP请求!

什么是二次预构建

由于在项目启动时 vite 会通过代码词法分析,收集所有第三方依赖并且合并/缓存第三方依赖以提升代码运行的性能,但是在开发过程中可能出现主动引入一些新的第三方依赖,或者有一些模块代码中具有动态依赖,只有在项目运行时才会被加载,这种情况下,vite 无法预先收集到,因此需要二次预构建。

  • plugin 在运行过程中,动态给源码注入了新的第三方依赖;

  • 动态依赖在代码运行时,才可以确定最终的 url;

当出现这两种情况时,Vite 会触发二次预构建。