Vite 中的 HMR(模块热替换,Hot Module Replacement)原理可以概述如下:
启动开发服务器:Vite 启动时,会启动一个开发服务器,该服务器负责监听文件系统的更改,并提供对应用中每个模块的特殊处理版本。这些特殊版本的模块包含了一些额外的元数据和与服务器通信的能力,为 HMR 的实现打下基础。
模块转换与监控:当开发服务器接收到浏览器对模块的请求时,它会根据需要即时转换模块(如使用 esbuild 进行快速编译),并将转换后的模块发送给浏览器。同时,服务器持续监控文件系统,一旦检测到任何模块的源代码发生变化,就会立即重新编译该模块。
WebSocket 通信:Vite 利用 WebSocket 建立了开发服务器与浏览器之间的实时双向通信通道。这意味着服务器可以在不刷新页面的情况下,直接向浏览器推送关于模块更新的消息。
模块替换:当浏览器接收到更新的通知后,它会使用 HMR API 来请求更新后的模块。Vite 的 HMR 实现并不直接替换最初导入的模块,而是依赖于模块本身来管理其内部的更新。如果一个模块重新导出了从其他依赖中导入的内容,它需要自己负责更新这些重新导出的模块。Vite 的这种简化实现方式避免了生成代理模块的开销,对于多数开发场景而言已足够高效。
状态保留与更新:在模块替换的过程中,页面的状态得以保留,用户界面会无缝地反映代码的变化,而无需刷新页面或丢失应用状态。这对于提升开发效率非常关键,因为开发者可以即时查看代码修改的效果。
HMR API:Vite 提供了一套原生 ESM 的 HMR API,允许框架或开发者通过 hot.accept()
方法来显式地处理依赖项的更新,这使得框架如 Vue、React(通过 Fast Refresh)等能够提供更加精确和高效的更新机制。
综上所述,Vite 的 HMR 实现依靠于现代浏览器对 ESM 的支持、WebSocket 的实时通信能力、以及对模块更新的智能管理,共同实现了高效且对开发者友好的热更新体验。