Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HMR API] add the ability to remove listeners added using import.meta.hot.on() #14185

Closed
4 tasks done
Tofandel opened this issue Aug 23, 2023 · 3 comments · Fixed by #14518
Closed
4 tasks done

[HMR API] add the ability to remove listeners added using import.meta.hot.on() #14185

Tofandel opened this issue Aug 23, 2023 · 3 comments · Fixed by #14518

Comments

@Tofandel
Copy link

Tofandel commented Aug 23, 2023

Description

While the ability to add events to communicate with the vite websocket is great, it would be even greater if we could also remove the events we added using import.meta.hot.on('event', () => {})

Suggested solution

Add an off and maybe a once method, or return a callback from on that can be called to remove the listener

Alternative

There is no alternative, right now once an event is added it can never be removed

Code reference

on(event, cb) {
const addToMap = (map: Map<string, any[]>) => {
const existing = map.get(event) || []
existing.push(cb)
map.set(event, existing)
}
addToMap(customListenersMap)
addToMap(newListeners)
},

Validations

@bluwy
Copy link
Member

bluwy commented Sep 17, 2023

I think this is a nice idea. Can you further explain your usecase for this feature?

@Tofandel
Copy link
Author

It's mostly for advanced use case with vite, where you create a plugin to communicate with the websocket

Because those events can basically be used to request something from vite, you'll send an event with send and wait for the answer with .on but you don't need to keep listening once you received your result so you need to be able to remove the listener or you end up with memory leaks

@bluwy
Copy link
Member

bluwy commented Sep 18, 2023

Alright 👍 So sounds like the main use-case is to listen to something once. I guess you could used a temporary variable to block it so the listener only runs once. FYI import.meta.env.on has self cleanups so there shouldn't be memory leaks:

// clear stale custom event listeners
const staleListeners = ctxToListenersMap.get(ownerPath)
if (staleListeners) {
for (const [event, staleFns] of staleListeners) {
const listeners = customListenersMap.get(event)
if (listeners) {
customListenersMap.set(
event,
listeners.filter((l) => !staleFns.includes(l)),
)
}
}
}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants