vite中的依赖预构建 到底是什么 做了什么

1. 什么是依赖预构建?

在现代前端开发中,项目中通常会依赖大量第三方库(如 lodashaxiosreact 等)。这些库通常是用 CommonJS 或其他格式编写的,而 Vite 的开发服务器是基于 ESM(原生 ES 模块)运行的。

为了让这些第三方库能够高效地被浏览器加载,Vite 会在开发服务器启动之前,对这些依赖进行一次预构建(Pre-Bundling),将它们转换为浏览器友好的 ESM 格式,并进行优化。

2. 为什么需要依赖预构建?

问题一:CommonJS 和 UMD 格式不兼容 ESM

  • 大多数 NPM 上的库使用 CommonJS 或 UMD 格式,这些格式不能直接被浏览器识别。
  • 如果不进行预构建,Vite 在运行时需要动态转换格式,性能会大打折扣。

问题二:模块的深层依赖解析慢

  • 许多第三方库会依赖其他库(深层依赖链),浏览器需要逐个解析这些依赖,可能会导致请求过多和加载缓慢。
  • 例如,lodash-es 中有许多子模块,如果不预构建,浏览器需要逐个请求这些模块,增加了网络开销。

问题三:重复解析

  • 如果多个文件引用了同一个依赖,浏览器会多次解析,造成性能浪费。

解决方案:Vite 的依赖预构建

  • Vite 使用 esbuild 将第三方依赖预先打包成单个 ESM 文件,避免了上述问题。
  • 预构建后的依赖会被缓存,只有在依赖发生变化时才会重新构建。

3. Vite 的依赖预构建流程

第一步:识别依赖

  • Vite 会扫描项目的 import 语句,识别出第三方依赖(通常是从 node_modules 中引入的库)。

  • 例如:

    javascript 复制代码
    import React from 'react';
    import _ from 'lodash';

    Vite 会将 reactlodash 识别为需要预构建的依赖。

第二步:使用 esbuild 进行预构建

  • Vite 使用 esbuild 对这些依赖进行一次性打包,将它们转换为 ESM 格式。
  • 例如,react 的 CommonJS 文件会被转换为浏览器可用的 ESM 文件。

第三步:缓存预构建结果

  • 预构建的依赖会被缓存到 node_modules/.vite 目录中。
  • 如果依赖没有发生变化,Vite 会直接使用缓存,而不会重复构建。

4. 依赖预构建的优化点

1. 合并模块

  • Vite 会将一个依赖及其子依赖合并为一个文件,减少浏览器的网络请求数量。
  • 例如,lodash-es 中的多个子模块会被合并为一个文件。

2. 提升解析速度

  • 通过 esbuild 的超快解析能力(用 Go 编写,比 JavaScript 实现快 10-100 倍),依赖预构建速度非常快。

3. 支持 Tree Shaking

  • 对于支持 Tree Shaking 的依赖(如 lodash-es),Vite 的预构建会保留模块的按需加载能力,避免打包无用代码。

4. 缓存机制

  • 预构建结果会被缓存到本地(node_modules/.vite),只有当依赖版本或配置发生变化时才会重新预构建,避免重复工作。

5. 配置依赖预构建

Vite 提供了一些配置选项来控制依赖预构建的行为。

自动预构建

  • 默认情况下,Vite 会自动识别项目中的第三方依赖并进行预构建。
  • 如果需要手动指定依赖,可以通过 optimizeDeps 配置。

常用配置选项

1. 强制预构建的依赖

  • 如果某些依赖没有被自动预构建,可以手动指定:

    arduino 复制代码
    export default {
      optimizeDeps: {
        include: ['lodash', 'axios']
      }
    }

2. 排除某些依赖

  • 如果某些依赖不需要预构建,可以排除:

    arduino 复制代码
    export default {
      optimizeDeps: {
        exclude: ['some-large-library']
      }
    }

3. 禁用预构建

  • 在特殊情况下,你可以禁用依赖预构建:

    arduino 复制代码
    export default {
      optimizeDeps: {
        disabled: true
      }
    }

6. 依赖预构建的效果

开发服务器启动速度提升

  • 通过预构建,Vite 避免了在启动时动态解析第三方依赖,大幅减少了开发服务器的启动时间。
  • 对于依赖复杂的大型项目,启动速度提升尤为显著。

减少浏览器请求

  • 预构建会将深层依赖合并为一个文件,减少浏览器的网络请求数量。

提升模块加载性能

  • 预构建后的依赖是 ESM 格式,浏览器可以直接加载,无需额外的动态转换。

7. 实际案例

假设项目中使用了以下依赖:

javascript 复制代码
import React from 'react';
import ReactDOM from 'react-dom';
import _ from 'lodash-es';
  • 未预构建:

    • 浏览器需要分别加载 reactreact-domlodash-es 的多个模块,加载时间较长。
  • 预构建后:

    • Vite 会将 reactreact-dom 合并为一个 ESM 文件,将 lodash-es 的子模块合并为另一个文件。
    • 浏览器只需加载两个文件,性能显著提升。

8. 总结

Vite 的依赖预构建通过以下方式提升了开发效率:

  • 使用 esbuild 对第三方依赖进行超快的预构建。
  • 将依赖转换为 ESM 格式,优化浏览器的加载性能。
  • 合并深层依赖,减少网络请求。
  • 缓存预构建结果,避免重复工作。

依赖预构建是 Vite 快速启动和高效模块加载的关键机制之一,使其在开发体验上相比 Webpack 等传统工具具有显著优势。

相关推荐
Moment7 分钟前
终于搞懂了!Source Map 是如何让你定位打包后代码的?💥 💥 💥
前端·javascript·webpack
yang_love101128 分钟前
Webpack vs Vite:深度对比与实战示例,如何选择最佳构建工具?
前端·webpack·node.js
好_快31 分钟前
Lodash源码阅读-keysIn
前端·javascript·源码阅读
好_快32 分钟前
Lodash源码阅读-nativeKeysIn
前端·javascript·源码阅读
好_快34 分钟前
Lodash源码阅读-baseKeysIn
前端·javascript·源码阅读
Good luck—dys37 分钟前
VUE如何后端控制及动态路由详细讲解
前端·javascript·vue.js
好_快40 分钟前
Lodash源码阅读-baseGetAllKeys
前端·javascript·源码阅读
裁二尺秋风2 小时前
Nginx — Nginx处理Web请求机制解析
前端·nginx
excel2 小时前
webpack 核心编译器 第五节
前端