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

fix: return the same instance of ModuleNode for the same EnvironmentModuleNode #18455

Merged

Conversation

sapphi-red
Copy link
Member

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 because moduleGraph.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.

@sapphi-red sapphi-red added p3-downstream-blocker Blocking the downstream ecosystem to work properly (priority) feat: environment API Vite Environment API labels Oct 25, 2024
Comment on lines +472 to 491
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)
}
Copy link
Member Author

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.

Copy link
Member

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.

@sapphi-red

This comment was marked as outdated.

@vite-ecosystem-ci

This comment was marked as outdated.

@sapphi-red sapphi-red force-pushed the fix/backward-compat-mixed-module-graph branch from 86ca139 to c17b6aa Compare October 25, 2024 02:47
@sapphi-red
Copy link
Member Author

/ecosystem-ci run

@vite-ecosystem-ci

This comment was marked as outdated.

@vite-ecosystem-ci
Copy link

📝 Ran ecosystem CI on c17b6aa: Open

suite result latest scheduled
astro failure failure
nuxt failure success
redwoodjs failure failure
remix failure failure
sveltekit failure failure
vike failure failure
vite-plugin-svelte success failure
vitest failure failure

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

@sapphi-red
Copy link
Member Author

sapphi-red commented Oct 25, 2024

nuxt fails with main branch too (ran locally).

Copy link
Member

@patak-dev patak-dev left a 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.

@patak-dev patak-dev merged commit 5ead461 into vitejs:main Oct 25, 2024
14 checks passed
@sapphi-red sapphi-red deleted the fix/backward-compat-mixed-module-graph branch October 25, 2024 10:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat: environment API Vite Environment API p3-downstream-blocker Blocking the downstream ecosystem to work properly (priority)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants