菜单

模块热更新

相关源文件

本文档介绍了 Vite 的热模块替换 (HMR) 系统,该系统能够在开发过程中实时更新模块,而不会丢失应用程序状态。HMR 系统包含在浏览器中运行的客户端 JavaScript、通过开发服务器进行的服务器端协调以及用于通信的基于 WebSocket 的传输层。

有关更广泛的开发服务器功能的更多信息,请参阅开发服务器。有关扩展 HMR 功能的插件系统的详细信息,请参阅插件系统

架构概述

Vite 的 HMR 系统通过客户端-服务器架构运行,其中浏览器与开发服务器保持持久的 WebSocket 连接。当文件发生更改时,服务器会分析依赖项并将定向的更新指令发送给已连接的客户端。

HMR 系统组件

来源:packages/vite/src/client/client.ts1-461 packages/vite/types/hmrPayload.d.ts1-75 packages/vite/types/hot.d.ts1-40

消息流架构

来源:packages/vite/src/client/client.ts171-303 packages/vite/types/hmrPayload.d.ts20-38

客户端实现

HMR 客户端的核心实现围绕着 HMRClient 类和 HMRContext,后者向应用程序代码提供 import.meta.hot API。

核心客户端组件

组件文件位置目的
HMRClientpackages/vite/src/shared/hmr.ts管理更新队列和模块重新加载
HMRContextpackages/vite/src/shared/hmr.ts实现 import.meta.hot API
ErrorOverlaypackages/vite/src/client/overlay.ts209-292显示编译错误
WebSocket 传输packages/vite/src/client/client.ts41-104处理服务器通信

客户端初始化

HMR 客户端在应用程序启动时建立连接

客户端在packages/vite/src/client/client.ts13-22 中注入的常量来接收配置。

  • __HMR_PROTOCOL____HMR_HOSTNAME____HMR_PORT__ - 连接参数
  • __HMR_TIMEOUT__ - WebSocket 超时配置
  • __HMR_ENABLE_OVERLAY__ - 错误覆盖层设置
  • __WS_TOKEN__ - 认证令牌

来源:packages/vite/src/client/client.ts24-104 packages/vite/src/node/plugins/clientInjections.ts17-122

模块更新处理

当客户端接收到更新消息时,它会通过结构化的管道进行处理

packages/vite/src/client/client.ts193-241 中处理 JavaScript 和 CSS 更新的方式不同,以优化用户体验。

来源:packages/vite/src/client/client.ts171-241 packages/vite/types/hmrPayload.d.ts20-38

Import.meta.hot API

import.meta.hot API 通过 ViteHotContext 接口实现,为开发者提供了对模块如何响应更新的精细控制。

核心 API 方法

方法签名目的
accept()accept(cb?: Function)自接受模块更新
accept(deps, cb)accept(deps: string[], cb: Function)接受依赖项更新
acceptExports()acceptExports(exports: string[], cb?: Function)接受特定导出更新
dispose()dispose(cb: Function)更新前清理
invalidate()invalidate(message?: string)强制完全重新加载

API 使用模式

来自playground/hmr/hmr.ts42-83 的自接受模块实现示例

来源:packages/vite/types/hot.d.ts7-39 playground/hmr/hmr.ts42-153 docs/guide/api-hmr.md71-200

WebSocket 传输层

HMR 系统使用 WebSocket 连接实现开发服务器和浏览器客户端之间的实时双向通信。

连接管理

packages/vite/src/client/client.ts53-94 中的连接逻辑,实现了在主要 WebSocket 端点不可访问的网络配置下的备用机制。

消息类型和负载

HMR 协议为不同操作定义了特定的负载类型

Payload Type接口目的
ConnectedPayload{ type: 'connected' }确认连接
UpdatePayload{ type: 'update', updates: Update[] }模块更新
FullReloadPayload{ type: 'full-reload', path?: string }页面重新加载
ErrorPayload{ type: 'error', err: ErrorInfo }编译错误
CustomPayload{ type: 'custom', event: string, data?: any }插件事件

来源:packages/vite/src/client/client.ts41-104 packages/vite/types/hmrPayload.d.ts3-74

错误处理和覆盖层

发生编译错误时,Vite 会显示一个用户友好的错误覆盖层,提供详细的调试信息。

错误覆盖层系统

ErrorOverlay 类在 packages/vite/src/client/overlay.ts209-292 创建了一个基于 shadow DOM 的覆盖层,它

  • 显示带语法高亮的错误消息
  • 显示带有可点击链接的文件位置
  • 提供用于调试的堆栈跟踪
  • 提供清除说明

错误处理。

错误信息包含结构化数据,以增强调试能力

来源: packages/vite/src/client/overlay.ts209-298 packages/vite/types/hmrPayload.d.ts58-74 packages/vite/src/client/client.ts282-295 docs/guide/api-hmr.md217-229 packages/vite/src/client/client.ts282-295

插件集成

HMR 系统通过插件 API 为插件提供了扩展和自定义更新行为的钩子。

插件 HMR 钩子

示例插件实现来自 playground/hmr/vite.config.ts18-40

客户端-服务器通信

插件可以建立双向通信通道

来源: playground/hmr/vite.config.ts17-100 playground/hmr/hmr.ts148-152 docs/guide/api-hmr.md217-229 packages/vite/src/client/client.ts282-295

配置和注入

HMR 客户端通过 clientInjectionsPlugin 管理的编译时常量注入来接收配置。

配置注入过程

clientInjectionsPluginpackages/vite/src/node/plugins/clientInjections.ts17-117 通过替换占位符常量来注入 HMR 配置

占位符运行时值目的
__HMR_PROTOCOL__'ws''wss'WebSocket 协议
__HMR_HOSTNAME__服务器主机名连接目标
__HMR_PORT__HMR 端口号WebSocket 端口
__HMR_BASE__应用程序基础 URL 路径URL 基础路径
__HMR_TIMEOUT__超时值连接超时
__HMR_ENABLE_OVERLAY__布尔标志错误覆盖层开关

环境集成

HMR 系统通过 packages/vite/types/importMeta.d.ts14-31 与 Vite 的环境变量集成,提供了对以下内容的访问:

  • import.meta.env.MODE - 当前模式 (development/production)
  • import.meta.env.DEV - 开发标志
  • import.meta.env.BASE_URL - 应用程序基础 URL

来源: packages/vite/src/node/plugins/clientInjections.ts68-95 packages/vite/types/importMeta.d.ts23-31