使用Bun的全栈开发服务器时,默认启用HMR。
import.meta.hot API参考
Bun实现了一个客户端HMR API,该API模仿了Vite的import.meta.hot API。可以通过if (import.meta.hot)来检查它,并在生产环境中进行树摇(tree-shaking)。
HMR API仍在开发中。某些功能缺失。可以在
Bun.serve中通过设置开发选项为{ hmr: false }来禁用HMR。API方法
| 方法 | 状态 | 注释 |
|---|---|---|
hot.accept() | ✅ | 表明热更新可以被优雅地替换。 |
hot.data | ✅ | 在模块评估之间持久化数据。 |
hot.dispose() | ✅ | 添加一个回调函数,当模块即将被替换时运行。 |
hot.invalidate() | ❌ | |
hot.on() | ✅ | 附加事件监听器 |
hot.off() | ✅ | 从on中移除事件监听器。 |
hot.send() | ❌ | |
hot.prune() | 🚧 | 注意:回调函数当前永远不会被调用。 |
hot.decline() | ✅ | 无操作以匹配Vite的import.meta.hot |
import.meta.hot.accept()
accept()方法表明模块可以进行热替换。在不带参数调用时,表明此模块可以通过重新评估文件来简单地替换。热更新后,此模块的导入者将自动被修补。
index.ts导入的文件创建了一个热重载边界。这意味着每当foo.ts或其任何依赖项被保存时,更新将向上传播到index.ts并重新评估。导入index.ts的文件将被修补以导入新版本的getNegativeCount()。如果仅更新index.ts,则只有该文件将被重新评估,并且重用foo.ts中的计数器。
这可以与import.meta.hot.data结合使用,将状态从先前的模块转移到新模块。
当没有模块调用
import.meta.hot.accept()(并且没有React Fast Refresh或插件为您调用它)时,
页面将在文件更新时重新加载,并显示一个控制台警告,指示哪些文件被无效化。如果完全依赖页面重新加载更有意义,则可以安全地忽略此警告。带回调
当提供一个回调时,import.meta.hot.accept将像在Vite中一样工作。它不会修补此模块的导入者,而是使用新模块调用回调。
接受其他模块
带多个依赖项
import.meta.hot.data
import.meta.hot.data在热替换期间保持模块实例之间的状态,使数据可以从先前版本传输到新版本。当写入import.meta.hot.data时,Bun还将此模块标记为能够自接受(相当于调用import.meta.hot.accept())。
data被内联为{},这意味着它不能用作状态持有者。
import.meta.hot.dispose()
附加一个on-dispose回调。这将在以下情况下被调用:- 在模块被另一个副本替换之前(在加载下一个副本之前)
- 在模块被分离后(移除对此模块的所有导入,参见
import.meta.hot.prune())
import.meta.hot.prune()
附加一个on-prune回调。当此模块的所有导入都被移除时,但该模块之前已加载过,将调用此回调。 这可以用于清理模块加载时创建的资源。与import.meta.hot.dispose()不同,这与accept和data更好地配合使用,以管理有状态资源。管理WebSocket的完整示例:
如果改用
dispose,WebSocket将在每次热更新时关闭并重新打开。两个版本的代码都将在导入的文件更新时防止页面重新加载。import.meta.hot.on()和off()
on()和off()用于监听来自HMR运行时的事件。事件名称以前缀开头,以便插件之间不会冲突。
内置事件
| 事件 | 发生时机 |
|---|---|
bun:beforeUpdate | 在应用热更新之前。 |
bun:afterUpdate | 在应用热更新之后。 |
bun:beforeFullReload | 在完全页面重新加载之前。 |
bun:beforePrune | 在调用prune回调之前。 |
bun:invalidate | 当使用import.meta.hot.invalidate()使模块无效时 |
bun:error | 当构建或运行时错误发生时 |
bun:ws:disconnect | 当HMR WebSocket连接丢失时。这可能表明开发服务器离线。 |
bun:ws:connect | 当HMR WebSocket连接或重新连接时。 |
为与Vite兼容,上述事件也通过
vite:*前缀而不是bun:*前缀提供。