sveltejs / vite-plugin-svelte

Svelte plugin for http://vitejs.dev/
MIT License
844 stars 103 forks source link

`vite dev` crashes with call stack overflow on file save #690

Closed JeroenvdV closed 1 year ago

JeroenvdV commented 1 year ago

Describe the bug

When I save a file (in vscode) while vite dev is running, it terminates with the following error:

Exception in PromiseRejectCallback:
file:///home/jeroen/Files/Booost/booost-extension/sveltekit/node_modules/.pnpm/vite@4.4.4_@types+node@20.4.2_sass@1.63.6/node_modules/vite/dist/node/chunks/dep-abb4f102.js:65020
    });
    ^

RangeError: Maximum call stack size exceeded

node:fs:289
function existsSync(path) {
                   ^

RangeError: Maximum call stack size exceeded
    at Object.existsSync (node:fs:289:20)
    at file:///home/jeroen/Files/Booost/booost-extension/sveltekit/node_modules/.pnpm/@sveltejs+vite-plugin-svelte@2.4.2_svelte@4.0.5_vite@4.4.4/node_modules/@sveltejs/vite-plugin-svelte/src/utils/watch.js:23:11
    at Array.forEach (<anonymous>)
    at emitChangeEventOnDependants (file:///home/jeroen/Files/Booost/booost-extension/sveltekit/node_modules/.pnpm/@sveltejs+vite-plugin-svelte@2.4.2_svelte@4.0.5_vite@4.4.4/node_modules/@sveltejs/vite-plugin-svelte/src/utils/watch.js:22:14)
    at file:///home/jeroen/Files/Booost/booost-extension/sveltekit/node_modules/.pnpm/@sveltejs+vite-plugin-svelte@2.4.2_svelte@4.0.5_vite@4.4.4/node_modules/@sveltejs/vite-plugin-svelte/src/utils/watch.js:94:66
    at Array.forEach (<anonymous>)
    at FSWatcher.<anonymous> (file:///home/jeroen/Files/Booost/booost-extension/sveltekit/node_modules/.pnpm/@sveltejs+vite-plugin-svelte@2.4.2_svelte@4.0.5_vite@4.4.4/node_modules/@sveltejs/vite-plugin-svelte/src/utils/watch.js:94:44)
    at FSWatcher.emit (node:events:523:35)
    at FSWatcher.emit (node:domain:489:12)
    at file:///home/jeroen/Files/Booost/booost-extension/sveltekit/node_modules/.pnpm/@sveltejs+vite-plugin-svelte@2.4.2_svelte@4.0.5_vite@4.4.4/node_modules/@sveltejs/vite-plugin-svelte/src/utils/watch.js:27:13

Node.js v20.1.0
 ELIFECYCLE  Command failed with exit code 1.

This refers to the following code in vite-plugin-svelte/src/utils/watch.js:

    const emitChangeEventOnDependants = (filename) => {
        const dependants = cache.getDependants(filename);
        dependants.forEach((dependant) => {
            if (fs.existsSync(dependant)) {
                log.debug(
                    `emitting virtual change event for "${dependant}" because depdendency "${filename}" changed`
                );
                watcher.emit('change', dependant);
            }
        });
    };

When adding some debug logs, I see that dependants includes filename, which causes this to infinitely recurse.

Please let me know what more information I can add to clarify (and/or work around) this problem.

Reproduction URL

https://vite.new/svelte

Reproduction

I'm truly sorry for not providing a reproduction but I need help understanding in which direction to look at how to produce one for this specific symptom, and whether to look for it in this package at all.

Logs

2023-07-18T12:10:04.421Z vite:hmr [file change] src/lib/sidebar/Sidebar.svelte
2023-07-18T12:10:04.421Z vite:vite-plugin-svelte emitting virtual change event for "/home/jeroen/Files/Booost/booost-extension/sveltekit/src/lib/sidebar/Sidebar.svelte" because depdendency "/home/jeroen/Files/Booost/booost-extension/sveltekit/src/lib/sidebar/Sidebar.svelte" changed
2023-07-18T12:10:04.421Z vite:hmr [file change] src/lib/sidebar/Sidebar.svelte
2023-07-18T12:10:04.421Z vite:vite-plugin-svelte emitting virtual change event for "/home/jeroen/Files/Booost/booost-extension/sveltekit/src/lib/sidebar/Sidebar.svelte" because depdendency "/home/jeroen/Files/Booost/booost-extension/sveltekit/src/lib/sidebar/Sidebar.svelte" changed
2023-07-18T12:10:04.421Z vite:hmr [file change] src/lib/sidebar/Sidebar.svelte
2023-07-18T12:10:04.421Z vite:vite-plugin-svelte emitting virtual change event for "/home/jeroen/Files/Booost/booost-extension/sveltekit/src/lib/sidebar/Sidebar.svelte" because depdendency "/home/jeroen/Files/Booost/booost-extension/sveltekit/src/lib/sidebar/Sidebar.svelte" changed
2023-07-18T12:10:04.421Z vite:hmr [file change] src/lib/sidebar/Sidebar.svelte
2023-07-18T12:10:04.421Z vite:vite-plugin-svelte emitting virtual change event for "/home/jeroen/Files/Booost/booost-extension/sveltekit/src/lib/sidebar/Sidebar.svelte" because depdendency "/home/jeroen/Files/Booost/booost-extension/sveltekit/src/lib/sidebar/Sidebar.svelte" changed
2023-07-18T12:10:04.421Z vite:hmr [file change] src/lib/sidebar/Sidebar.svelte
2023-07-18T12:10:04.422Z vite:vite-plugin-svelte emitting virtual change event for "/home/jeroen/Files/Booost/booost-extension/sveltekit/src/lib/sidebar/Sidebar.svelte" because depdendency "/home/jeroen/Files/Booost/booost-extension/sveltekit/src/lib/sidebar/Sidebar.svelte" changed
2023-07-18T12:10:04.422Z vite:hmr [file change] src/lib/sidebar/Sidebar.svelte
2023-07-18T12:10:04.422Z vite:vite-plugin-svelte emitting virtual change event for "/home/jeroen/Files/Booost/booost-extension/sveltekit/src/lib/sidebar/Sidebar.svelte" because depdendency "/home/jeroen/Files/Booost/booost-extension/sveltekit/src/lib/sidebar/Sidebar.svelte" changed
2023-07-18T12:10:04.422Z vite:hmr [file change] src/lib/sidebar/Sidebar.svelte
2023-07-18T12:10:04.422Z vite:vite-plugin-svelte emitting virtual change event for "/home/jeroen/Files/Booost/booost-extension/sveltekit/src/lib/sidebar/Sidebar.svelte" because depdendency "/home/jeroen/Files/Booost/booost-extension/sveltekit/src/lib/sidebar/Sidebar.svelte" changed
2023-07-18T12:10:04.422Z vite:hmr [file change] src/lib/sidebar/Sidebar.svelte

System Info

System:
    OS: Linux 6.2 Ubuntu 23.04 23.04 (Lunar Lobster)
    CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
    Memory: 21.46 GB / 30.87 GB
    Container: Yes
    Shell: 5.2.15 - /bin/bash
  Binaries:
    Node: 20.1.0 - ~/.nvm/versions/node/v20.1.0/bin/node
    npm: 9.6.4 - ~/.nvm/versions/node/v20.1.0/bin/npm
    pnpm: 8.6.3 - ~/.local/share/pnpm/pnpm
  npmPackages:
    @sveltejs/adapter-vercel: ^3.0.2 => 3.0.2 
    @sveltejs/kit: ^1.22.3 => 1.22.3 
    svelte: ^4.0.5 => 4.0.5 
    vite: ^4.4.4 => 4.4.4
dominikg commented 1 year ago

Please provide a link to a minimal reproduction. This is required.

From your description alone it is unclear how or why a .svelte file would end up as a preprocessor dependency of itself.

bluwy commented 1 year ago

Maybe it would make sense for us to skip the change event if dependant === filename? I think it's a simple enough change, but would also be nice to know how it's being triggered. Things like Svelte preprocessors can affect it.

JeroenvdV commented 1 year ago

Again sorry for not providing a reproduction yet, I haven't been able to create one because I don't understand the problem well enough. Thank you for responding anyway, it's much appreciated!

I have added an if-statement that skips dependant === filename, and then I still see an infinite loop, but it bounces back and forth between two Svelte components now. So, in addition to a file being its own dependant, it seems there can be circular dependencies in the graph in other ways.

This must mean the code that builds the dependency list/graph affects this problem, but I haven't found out where that is done and how it works yet, or how my own code is affecting it to lead to this problem. Besides this issue, my code works/builds/runs seemingly fine and there is no obvious circular dependency.

dominikg commented 1 year ago

@JeroenvdV are you able to provide a reproduction for this?

andriytyurnikov commented 12 months ago

@JeroenvdV commenting out helped me ;)

watcher.emit('change', dependant);