-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
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
fix: return the same instance of ModuleNode for the same EnvironmentModuleNode #18455
fix: return the same instance of ModuleNode for the same EnvironmentModuleNode #18455
Conversation
class DualWeakMap<K1 extends WeakKey, K2 extends WeakKey, V> { | ||
private map = new WeakMap<K1 | object, WeakMap<K2 | object, V>>() | ||
private undefinedKey = {} | ||
|
||
get(key1: K1 | undefined, key2: K2 | undefined): V | undefined { | ||
const k1 = key1 ?? this.undefinedKey | ||
const k2 = key2 ?? this.undefinedKey | ||
return this.map.get(k1)?.get(k2) | ||
} | ||
|
||
set(key1: K1 | undefined, key2: K2 | undefined, value: V): void { | ||
const k1 = key1 ?? this.undefinedKey | ||
const k2 = key2 ?? this.undefinedKey | ||
if (!this.map.has(k1)) { | ||
this.map.set(k1, new Map<K2, V>()) | ||
} | ||
|
||
const m = this.map.get(k1)! | ||
m.set(k2, value) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Due to the simplicity of this implementation, a memory leak occurs in one particular case.
const dualWeakMap = new DualWeakMap()
const k1 = {}
const k2 = {}
dualWeakMap.set(k1, k2)
//
// some time passes and k2 gets dropped from memory, but k1 was kept
//
// this should return false because there's no entries in `dualWeakMap.map.get(k1)`
// but this return true
// since this implementation does not remove the inner map when the entry in the inner map is dropped
dualWeakMap.map.has(k1)
But I think this is fine for our case. Modules doesn't get dropped usually, and I assume the memory size of an empty Map is not that big.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I think it should be fine too. If k2 (which refers to the ssrModule
) gets dropped and k1 (the clientModule
) still exists, then I think it'll at least be cached with the clientModule
+ undefinedKey
pair so the weakmap is still useful.
The tricky part I guess is that undefinedKey
would always exist which would cause the memory leak.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
86ca139
to
c17b6aa
Compare
/ecosystem-ci run |
This comment was marked as outdated.
This comment was marked as outdated.
📝 Ran ecosystem CI on
✅ analogjs, histoire, ladle, laravel, marko, previewjs, quasar, qwik, rakkas, storybook, unocss, vite-environment-examples, vite-plugin-pwa, vite-plugin-react, vite-plugin-react-swc, vite-plugin-vue, vite-setup-catalogue, vitepress, vuepress |
nuxt fails with main branch too (ran locally). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uh, nice one Sapphi! This is a very interesting approach. Hopefully we'll see the ecosystem move away from server.moduleGraph
so we can forget this file ever existed at one point.
Description
This PR should fix the vite-plugin-svelte fail (https://github.com/vitejs/vite-ecosystem-ci/actions/runs/11473350317/job/31927446107) by improving backward compat of the ModuleGraph.
It was failing because this
inline_styles
function never resolved.https://github.com/sveltejs/kit/blob/dcbe4222a194c5f90cfc0fc020cf065f7a4e4c46/packages/kit/src/exports/vite/dev/index.js#L189-L194
This
find_deps
function was recursively called infinitely becausemoduleGraph.getModuleByUrl
returned a new instance for the same ModuleNode.https://github.com/sveltejs/kit/blob/dcbe4222a194c5f90cfc0fc020cf065f7a4e4c46/packages/kit/src/exports/vite/dev/index.js#L578-L614
This PR prevents that happening by caching the ModuleNode.