Vite系列课程 | 6. Vite 的依赖预加载和预构建,7. Vite 配置文件处理细节

server/2024/12/19 8:05:58/

6. Vite 的依赖预加载和预构建

Vite 能够显著提升开发体验的关键特性之一就是其依赖预加载和预构建机制。

6.1 依赖预加载与路径处理

当我们使用 ES 模块导入依赖时,例如:

import Vue from 'vue';
import someModule from './some-module.js';

Vite 在构建过程中会对这些依赖进行预加载。对于非绝对路径(/ 开头)或相对路径(./../ 开头)的引用,Vite 会自动进行路径补全,使其能够正确解析。

Vite 通过以下方式处理路径:

  • node_modules 解析: 对于不带路径前缀的模块名(如 vue),Vite 会自动在 node_modules 目录中查找。
  • 相对路径和绝对路径解析: 对于相对路径和绝对路径,Vite 按照标准 ES 模块的解析规则进行处理。
  • URL 哈希: Vite 使用 URL 哈希来管理缓存和依赖版本,确保浏览器能够加载到正确的版本。例如,一个依赖的 URL 可能是 /node_modules/.vite/deps/vue.js?v=f3b2a9c1
6.2 依赖的查找过程

Vite 在解析依赖时,会从当前文件的目录开始向上查找,直到找到 node_modules 目录或到达项目根目录。这个查找过程类似于 Node.js 的模块解析机制。

6.3 开发与生产环境的区别
  • 开发环境 (vite dev): Vite 使用原生 ES 模块,按需编译,并动态预构建依赖。每次依赖更新后,Vite 会确保其相对路径的正确性,实现快速加载和热更新。
  • 生产环境 (vite build): Vite 使用 Rollup 进行打包。Rollup 专注于生成优化的代码,将多个模块合并成更少的文件,减少 HTTP 请求次数和文件体积。预构建的依赖也会被 Rollup 打包到最终的构建产物中。
6.4 依赖预构建与缓存机制:提升性能的关键

Vite 在预构建依赖时,执行以下操作:

  1. 依赖分析: Vite 分析项目代码,找出所有使用的依赖。
  2. 转换格式: 使用 esbuild 将 CommonJS 模块转换为 ES 模块。这是至关重要的一步,因为 Vite 主要处理 ES 模块。
  3. 缓存: 将转换后的依赖缓存到 node_modules/.vite/deps 目录中。这样,在后续构建中,Vite 可以直接使用缓存,避免重复转换,显著提升构建速度。

为什么需要 esbuild?

许多 npm 包仍然以 CommonJS 格式发布。由于 Vite 主要处理 ES 模块,因此需要使用 esbuild 将 CommonJS 模块转换为 ES 模块,以确保兼容性。

示例:

假设有以下模块:

// a.js
export default function a() {}// b.js
export { default as a } from './a.js';

经过 Vite 处理后,可能会被转换为:

// .vite/deps/a.js
function a() {}
export { a as default };// .vite/deps/b.js
import { a as __vite_default_export_0__ } from './a.js?v=someHash';
export { __vite_default_export_0__ as a };

通过这种方式,Vite 解决了以下问题:

  • 不同模块格式的兼容性: 统一转换为 ES 模块,使得不同格式的模块可以无缝集成。
  • 路径重写: 将依赖路径重写到 .vite/deps,便于管理和优化。
  • 减少网络请求: 将多个模块合并成更少的文件,减少浏览器请求次数,提升加载速度。
6.5 总结:优化开发和生产构建

Vite 的预加载和依赖预构建机制有效地提升了开发效率和构建性能。通过转换模块格式、合并文件、动态路径补全和缓存机制,Vite 大大减少了构建时间和网络传输开销,使开发者能够更专注于代码编写。

6.6 补充
6.6.1 为什么需要 esbuild?

如上所述,esbuild 的主要作用是将 CommonJS 等非 ES 模块格式转换为 ES 模块,以兼容 Vite 的构建流程。

6.6.2 配置是否依赖预构建 (optimizeDeps)

可以通过 vite.config.js 中的 optimizeDeps 选项来配置依赖预构建行为:

import { defineConfig } from 'vite';export default defineConfig({optimizeDeps: {exclude: ['some-package'], // 排除指定的依赖,不进行预构建include: ['other-package'], // 强制包含指定的依赖,即使 Vite 没有检测到},
});
  • exclude:指定不需要预构建的依赖。例如,一些库可能已经提供了 ES 模块版本,或者与 esbuild 不兼容。
  • include:强制包含某些依赖进行预构建。这在某些情况下很有用,例如,当某个依赖没有被静态分析正确检测到时。

7. Vite 配置文件处理细节

7.1 Vite 配置文件的语法提示
  • WebStorm: 提供最佳的语法补全和类型提示支持。
  • VS Code 和其他编辑器: 可以安装 Vite 相关的插件(如 VLS)或手动安装 @types/vite 来获得更好的语法提示。

带类型提示的写法:

import { defineConfig } from 'vite';export default defineConfig({// 配置选项
});
7.2 环境处理:更简洁的方式

Vite 提供了比 Webpack 更简洁的环境处理方式:

  • .env 文件: Vite 默认使用 .env 文件来管理环境变量。
    • .env:通用环境变量。
    • .env.local:本地开发环境变量(优先级高于 .env)。
    • .env.[mode]:特定模式的环境变量,如 .env.production.env.development
    • .env.[mode].local:特定模式的本地环境变量(优先级最高)。

Vite 会根据当前环境自动加载相应的 .env 文件。

  • Vite 配置的条件性: 可以在 vite.config.js 中根据 mode 参数进行条件配置:
import { defineConfig } from 'vite';export default defineConfig(({ mode }) => {if (mode === 'production') {return {build: {minify: 'esbuild', // 生产环境使用 esbuild 压缩},};} else {return {server: {port: 3000, // 开发环境使用 3000 端口},};}
});
7.3 补充
7.3.1 策略模式:更优雅的环境配置

可以使用策略模式来更优雅地处理不同环境的配置:

import { defineConfig, UserConfigExport } from 'vite';    const baseConfig: UserConfigExport = {// 基础配置
};const devConfig: UserConfigExport = {server: {port: 3000,},
};const prodConfig: UserConfigExport = {build: {minify: 'esbuild',},
};const envResolver = {build: () => ({ ...baseConfig, ...prodConfig }),serve: () => ({ ...baseConfig, ...devConfig }),
};export default defineConfig(({ command }) => {return envResolver[command]();
});

这种方式避免了大量的 if...else 语句,使配置代码更加清晰和易于维护。


http://www.ppmy.cn/server/151391.html

相关文章

docker 拉取镜像 | 创建容器 | 容器运行

拉取镜像 拉取镜像的命令:docker pull name (name换为你要拉取的镜像名) docker pull docker.1panel.live/hispark/qiankunbp:1.0.0 docker.1panel.live/hispark/qiankunbp:1.0.0为镜像名 拉取海思的镜像:(如果之前拉…

Spring Framework 路径遍历漏洞复现(CVE-2024-38819)

hu0x01 产品描述: Spring Framework 是一个功能强大的 Java 应用程序框架,旨在提供高效且可扩展的开发环境。它结合了轻量级的容器和依赖注入功能,提供了一种使用 POJO 进行容器配置和面向切面的编程的简单方法,以及一组用于AOP的模块。0x02 漏洞描述: Spring Framework 存…

XXE-Lab for PHP

进入环境 出现一个登录页面,输入任意 UserName 和 Psaaword ,使用bp抓取登录数据包 发送到重放器,点击“发送” 只修改 username 的值,查看右边的变化 只修改 password 的值,查看右边的变化 修改 username 和 password…

java二分查找算法详解

二分查找遵循分治策略,在升序排列的有序数组中查找元素。核心是反复减半搜索区间,先确定中间元素并与目标元素比较,若相等则查找成功返回其索引;若中间元素大于目标元素,就把搜索区间缩小到左半部分(更新右…

scp命令

scp(Secure Copy Protocol)是一种用于在不同主机之间安全传输文件的命令。使用 scp 命令,你可以将文件从本地计算机复制到远程计算机,或者从远程计算机复制到本地计算机。 以下是 scp 命令的基本语法和一些示例: 基本…

压力测试Jmeter简介

前提条件:要安装JDK 若不需要了解,请直接定位到左侧目录的安装环节。 1.引言 在现代软件开发中,性能和稳定性是衡量系统质量的重要指标。为了确保应用程序在高负载情况下仍能正常运行,压力测试变得尤为重要。Apache JMeter 是一…

Django中注册模型到Admin界面

Django 是一个高级的 Python Web 框架,它鼓励快速开发和干净、务实的设计。Django 自带了一个强大的管理后台(Admin),可以让开发者轻松地管理数据库中的数据。在这篇博文中,我们将详细介绍如何在 Django Admin 中注册一个模型,并定制其显示和管理方式。 前提条件 在开始…

Windows server 服务器网络安全管理之防火墙出站规则设置

Windows server 服务器网络安全管理之防火墙出站规则设置 创建一条出站规则 这条出站规则针对IE浏览器设置,指定路径 TCP协议和指定端口(多个端口的写法要注意) 所有IP,所有应用,都采用阻止 给这条规则进行命名…