3.2 KiB
3.2 KiB
name, description
| name | description |
|---|---|
| features-hmr | 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:
if (import.meta.hot) {
// HMR code
}
TypeScript Support
Add to tsconfig.json:
{
"compilerOptions": {
"types": ["vite/client"]
}
}
Self-Accepting Module
Module handles its own updates:
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:
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:
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:
if (import.meta.hot) {
import.meta.hot.prune((data) => {
// Cleanup when module is removed from page
})
}
Persistent Data
Pass data between module instances:
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:
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:
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:
// Client
if (import.meta.hot) {
import.meta.hot.send('my:event', { msg: 'Hello from client' })
}
Receive from server:
// Client
if (import.meta.hot) {
import.meta.hot.on('my:response', (data) => {
console.log(data.msg)
})
}
TypeScript for Custom Events
// 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 }
}
}