Files
gt-agent-company/.agents/skills/vite/references/features-hmr.md
sexygoat 3c62cc1cd1 first
2026-03-31 18:41:52 +08:00

201 lines
3.2 KiB
Markdown

---
name: features-hmr
description: Vite's Hot Module Replacement (HMR) client API
---
# HMR API
The HMR API is exposed via `import.meta.hot`. Primarily for framework and tooling authors.
## Conditional Guard
Always guard HMR code for tree-shaking in production:
```ts
if (import.meta.hot) {
// HMR code
}
```
## TypeScript Support
Add to `tsconfig.json`:
```json
{
"compilerOptions": {
"types": ["vite/client"]
}
}
```
## Self-Accepting Module
Module handles its own updates:
```ts
export const count = 1
if (import.meta.hot) {
import.meta.hot.accept((newModule) => {
if (newModule) {
console.log('updated: count is now', newModule.count)
}
})
}
```
## Accept Dependency Updates
React to changes in dependencies without self-reload:
```ts
import { foo } from './foo.js'
foo()
if (import.meta.hot) {
// Single dependency
import.meta.hot.accept('./foo.js', (newFoo) => {
newFoo?.foo()
})
// Multiple dependencies
import.meta.hot.accept(
['./foo.js', './bar.js'],
([newFooModule, newBarModule]) => {
// Handle updates
}
)
}
```
## Cleanup on Update
Clean up side effects before module is replaced:
```ts
function setupSideEffect() {
const interval = setInterval(() => {}, 1000)
return interval
}
const interval = setupSideEffect()
if (import.meta.hot) {
import.meta.hot.dispose((data) => {
clearInterval(interval)
})
}
```
## Prune Callback
Called when module is no longer imported:
```ts
if (import.meta.hot) {
import.meta.hot.prune((data) => {
// Cleanup when module is removed from page
})
}
```
## Persistent Data
Pass data between module instances:
```ts
if (import.meta.hot) {
// Mutate properties, don't reassign data itself
import.meta.hot.data.count = (import.meta.hot.data.count || 0) + 1
}
```
## Invalidate
Force propagation to importers:
```ts
if (import.meta.hot) {
import.meta.hot.accept((module) => {
if (cannotHandleUpdate(module)) {
import.meta.hot.invalidate() // Propagate to importers
}
})
}
```
## HMR Events
Listen to built-in events:
```ts
if (import.meta.hot) {
import.meta.hot.on('vite:beforeUpdate', (payload) => {
console.log('Update incoming')
})
import.meta.hot.on('vite:afterUpdate', (payload) => {
console.log('Update applied')
})
import.meta.hot.on('vite:beforeFullReload', () => {
console.log('Full reload')
})
import.meta.hot.on('vite:error', (error) => {
console.error('HMR error', error)
})
import.meta.hot.on('vite:ws:connect', () => {
console.log('WebSocket connected')
})
import.meta.hot.on('vite:ws:disconnect', () => {
console.log('WebSocket disconnected')
})
}
```
## Custom Events
Send events to server:
```ts
// Client
if (import.meta.hot) {
import.meta.hot.send('my:event', { msg: 'Hello from client' })
}
```
Receive from server:
```ts
// Client
if (import.meta.hot) {
import.meta.hot.on('my:response', (data) => {
console.log(data.msg)
})
}
```
## TypeScript for Custom Events
```ts
// events.d.ts
import 'vite/types/customEvent.d.ts'
declare module 'vite/types/customEvent.d.ts' {
interface CustomEventMap {
'my:event': { msg: string }
'my:response': { msg: string }
}
}
```
<!--
Source references:
- https://vite.dev/guide/api-hmr.html
-->