Skip to content

Commit 0d73473

Browse files
authoredNov 17, 2022
feat(hmr): invalidate message (#10946)
1 parent d9779c7 commit 0d73473

File tree

8 files changed

+32
-12
lines changed

8 files changed

+32
-12
lines changed
 

‎docs/guide/api-hmr.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ interface ViteHotContext {
3030

3131
dispose(cb: (data: any) => void): void
3232
decline(): void
33-
invalidate(): void
33+
invalidate(message?: string): void
3434

3535
// `InferCustomEventPayload` provides types for built-in Vite events
3636
on<T extends string>(
@@ -123,9 +123,9 @@ The `import.meta.hot.data` object is persisted across different instances of the
123123
124124
Calling `import.meta.hot.decline()` indicates this module is not hot-updatable, and the browser should perform a full reload if this module is encountered while propagating HMR updates.
125125
126-
## `hot.invalidate()`
126+
## `hot.invalidate(message?: string)`
127127
128-
A self-accepting module may realize during runtime that it can't handle a HMR update, and so the update needs to be forcefully propagated to importers. By calling `import.meta.hot.invalidate()`, the HMR server will invalidate the importers of the caller, as if the caller wasn't self-accepting.
128+
A self-accepting module may realize during runtime that it can't handle a HMR update, and so the update needs to be forcefully propagated to importers. By calling `import.meta.hot.invalidate()`, the HMR server will invalidate the importers of the caller, as if the caller wasn't self-accepting. This will log a message both in the browser console and in the terminal. You can pass a message to give some context on why the invalidation happened.
129129
130130
Note that you should always call `import.meta.hot.accept` even if you plan to call `invalidate` immediately afterwards, or else the HMR client won't listen for future changes to the self-accepting module. To communicate your intent clearly, we recommend calling `invalidate` within the `accept` callback like so:
131131

‎packages/vite/src/client/client.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -558,9 +558,12 @@ export function createHotContext(ownerPath: string): ViteHotContext {
558558
decline() {},
559559

560560
// tell the server to re-perform hmr propagation from this module as root
561-
invalidate() {
562-
notifyListeners('vite:invalidate', { path: ownerPath })
563-
this.send('vite:invalidate', { path: ownerPath })
561+
invalidate(message) {
562+
notifyListeners('vite:invalidate', { path: ownerPath, message })
563+
this.send('vite:invalidate', { path: ownerPath, message })
564+
console.debug(
565+
`[vite] invalidate ${ownerPath}${message ? `: ${message}` : ''}`
566+
)
564567
},
565568

566569
// custom events

‎packages/vite/src/node/server/hmr.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@ export function updateModules(
128128
file: string,
129129
modules: ModuleNode[],
130130
timestamp: number,
131-
{ config, ws }: ViteDevServer
131+
{ config, ws }: ViteDevServer,
132+
afterInvalidation?: boolean
132133
): void {
133134
const updates: Update[] = []
134135
const invalidatedModules = new Set<ModuleNode>()
@@ -166,7 +167,7 @@ export function updateModules(
166167

167168
if (needFullReload) {
168169
config.logger.info(colors.green(`page reload `) + colors.dim(file), {
169-
clear: true,
170+
clear: !afterInvalidation,
170171
timestamp: true
171172
})
172173
ws.send({
@@ -183,7 +184,7 @@ export function updateModules(
183184
config.logger.info(
184185
colors.green(`hmr update `) +
185186
colors.dim([...new Set(updates.map((u) => u.path))].join(', ')),
186-
{ clear: true, timestamp: true }
187+
{ clear: !afterInvalidation, timestamp: true }
187188
)
188189
ws.send({
189190
type: 'update',

‎packages/vite/src/node/server/index.ts

+14-2
Original file line numberDiff line numberDiff line change
@@ -505,11 +505,23 @@ export async function createServer(
505505
handleFileAddUnlink(normalizePath(file), server)
506506
})
507507

508-
ws.on('vite:invalidate', async ({ path }: InvalidatePayload) => {
508+
ws.on('vite:invalidate', async ({ path, message }: InvalidatePayload) => {
509509
const mod = moduleGraph.urlToModuleMap.get(path)
510510
if (mod && mod.isSelfAccepting && mod.lastHMRTimestamp > 0) {
511+
config.logger.info(
512+
colors.yellow(`hmr invalidate `) +
513+
colors.dim(path) +
514+
(message ? ` ${message}` : ''),
515+
{ timestamp: true }
516+
)
511517
const file = getShortName(mod.file!, config.root)
512-
updateModules(file, [...mod.importers], mod.lastHMRTimestamp, server)
518+
updateModules(
519+
file,
520+
[...mod.importers],
521+
mod.lastHMRTimestamp,
522+
server,
523+
true
524+
)
513525
}
514526
})
515527

‎packages/vite/types/customEvent.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export interface CustomEventMap {
1616

1717
export interface InvalidatePayload {
1818
path: string
19+
message: string | undefined
1920
}
2021

2122
export type InferCustomEventPayload<T extends string> =

‎packages/vite/types/hot.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export interface ViteHotContext {
2323

2424
dispose(cb: (data: any) => void): void
2525
decline(): void
26-
invalidate(): void
26+
invalidate(message?: string): void
2727

2828
on<T extends string>(
2929
event: T,

‎playground/hmr/__tests__/hmr.spec.ts

+1
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ if (!isBuild) {
145145
expect(browserLogs).toMatchObject([
146146
'>>> vite:beforeUpdate -- update',
147147
'>>> vite:invalidate -- /invalidation/child.js',
148+
'[vite] invalidate /invalidation/child.js',
148149
'[vite] hot updated: /invalidation/child.js',
149150
'>>> vite:afterUpdate -- update',
150151
'>>> vite:beforeUpdate -- update',

‎playground/react/__tests__/react.spec.ts

+2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ if (!isBuild) {
5454
)
5555
await untilUpdated(() => page.textContent('#parent'), 'Updated')
5656
expect(browserLogs).toMatchObject([
57+
'[vite] invalidate /hmr/no-exported-comp.jsx',
5758
'[vite] hot updated: /hmr/no-exported-comp.jsx',
5859
'[vite] hot updated: /hmr/parent.jsx',
5960
'Parent rendered'
@@ -79,6 +80,7 @@ if (!isBuild) {
7980
'context provider updated'
8081
)
8182
expect(browserLogs).toMatchObject([
83+
'[vite] invalidate /context/CountProvider.jsx',
8284
'[vite] hot updated: /context/CountProvider.jsx',
8385
'[vite] hot updated: /App.jsx',
8486
'[vite] hot updated: /context/ContextButton.jsx',

0 commit comments

Comments
 (0)
Please sign in to comment.