From 33a4ca7b7ba59ac66fb5b63ca373aa4c7c31b7f1 Mon Sep 17 00:00:00 2001 From: boreddad Date: Mon, 2 Oct 2023 19:04:48 -0400 Subject: [PATCH 1/3] feat: add off method to ViteHotContext --- packages/vite/src/client/client.ts | 18 ++++++++++++++++++ packages/vite/types/hot.d.ts | 4 ++++ 2 files changed, 22 insertions(+) diff --git a/packages/vite/src/client/client.ts b/packages/vite/src/client/client.ts index b909c1328a9a3b..911798d42d482e 100644 --- a/packages/vite/src/client/client.ts +++ b/packages/vite/src/client/client.ts @@ -605,6 +605,24 @@ export function createHotContext(ownerPath: string): ViteHotContext { addToMap(newListeners) }, + // remove a custom event + off(event, cb) { + const removeFromMap = (map: Map) => { + const existing = map.get(event) + if (existing === undefined) { + return + } + const pruned = existing.filter((l) => l !== cb) + if (pruned.length === 0) { + map.delete(event) + return + } + map.set(event, pruned) + } + removeFromMap(customListenersMap) + removeFromMap(newListeners) + }, + send(event, data) { messageBuffer.push(JSON.stringify({ type: 'custom', event, data })) sendMessageBuffer() diff --git a/packages/vite/types/hot.d.ts b/packages/vite/types/hot.d.ts index 5e8a450151606b..8ef92cda54c129 100644 --- a/packages/vite/types/hot.d.ts +++ b/packages/vite/types/hot.d.ts @@ -28,5 +28,9 @@ export interface ViteHotContext { event: T, cb: (payload: InferCustomEventPayload) => void, ): void + off( + event: T, + cb: (payload: InferCustomEventPayload) => void, + ): void send(event: T, data?: InferCustomEventPayload): void } From 2351628dff78b703a7bc6344f034b9f7890c4df1 Mon Sep 17 00:00:00 2001 From: boreddad Date: Tue, 3 Oct 2023 12:05:08 -0400 Subject: [PATCH 2/3] test: remove custom events added with import.meta.hot.on --- playground/hmr/__tests__/hmr.spec.ts | 8 ++++++++ playground/hmr/hmr.ts | 7 +++++++ playground/hmr/index.html | 1 + playground/hmr/vite.config.ts | 1 + 4 files changed, 17 insertions(+) diff --git a/playground/hmr/__tests__/hmr.spec.ts b/playground/hmr/__tests__/hmr.spec.ts index 508d3d7de46fc6..ed779bbc3099ac 100644 --- a/playground/hmr/__tests__/hmr.spec.ts +++ b/playground/hmr/__tests__/hmr.spec.ts @@ -177,6 +177,14 @@ if (!isBuild) { await untilUpdated(() => el.textContent(), 'edited') }) + test('plugin hmr remove custom events', async () => { + const el = await page.$('.toRemove') + editFile('customFile.js', (code) => code.replace('custom', 'edited')) + await untilUpdated(() => el.textContent(), 'edited') + editFile('customFile.js', (code) => code.replace('edited', 'custom')) + await untilUpdated(() => el.textContent(), 'edited') + }) + test('plugin client-server communication', async () => { const el = await page.$('.custom-communication') await untilUpdated(() => el.textContent(), '3') diff --git a/playground/hmr/hmr.ts b/playground/hmr/hmr.ts index 9748fdd1e8bc11..6273f071df270f 100644 --- a/playground/hmr/hmr.ts +++ b/playground/hmr/hmr.ts @@ -108,6 +108,8 @@ if (import.meta.hot) { text('.custom', msg) }) + import.meta.hot.on('custom:remove', removeCb) + // send custom event to server to calculate 1 + 2 import.meta.hot.send('custom:remote-add', { a: 1, b: 2 }) import.meta.hot.on('custom:remote-add-result', ({ result }) => { @@ -118,3 +120,8 @@ if (import.meta.hot) { function text(el, text) { document.querySelector(el).textContent = text } + +function removeCb({ msg }) { + text('.toRemove', msg) + import.meta.hot.off('custom:remove', removeCb) +} diff --git a/playground/hmr/index.html b/playground/hmr/index.html index 34d8eb631232a5..99df28951642a0 100644 --- a/playground/hmr/index.html +++ b/playground/hmr/index.html @@ -21,6 +21,7 @@
+
diff --git a/playground/hmr/vite.config.ts b/playground/hmr/vite.config.ts index b771693a5aab0f..1d952cf12be28a 100644 --- a/playground/hmr/vite.config.ts +++ b/playground/hmr/vite.config.ts @@ -13,6 +13,7 @@ export default defineConfig({ const content = await read() const msg = content.match(/export const msg = '(\w+)'/)[1] server.ws.send('custom:foo', { msg }) + server.ws.send('custom:remove', { msg }) } }, configureServer(server) { From af03bfd967ff0b9e0c7c615c96f03ca3b78e82f3 Mon Sep 17 00:00:00 2001 From: boreddad Date: Mon, 9 Oct 2023 08:22:15 -0400 Subject: [PATCH 3/3] docs: add hot.off to api-hmr document --- docs/guide/api-hmr.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/guide/api-hmr.md b/docs/guide/api-hmr.md index 8bbb5b0df9fbc1..d9d4200df22db4 100644 --- a/docs/guide/api-hmr.md +++ b/docs/guide/api-hmr.md @@ -37,6 +37,10 @@ interface ViteHotContext { event: T, cb: (payload: InferCustomEventPayload) => void, ): void + off( + event: T, + cb: (payload: InferCustomEventPayload) => void, + ): void send(event: T, data?: InferCustomEventPayload): void } ``` @@ -181,6 +185,10 @@ The following HMR events are dispatched by Vite automatically: Custom HMR events can also be sent from plugins. See [handleHotUpdate](./api-plugin#handlehotupdate) for more details. +## `hot.off(event, cb)` + +Remove callback from the event listeners + ## `hot.send(event, data)` Send custom events back to Vite's dev server.