Open dsgallups opened 2 days ago
This is quite an unusual bug. I noticed that in the output you will find
<!-- This file is generated by @sveltejs/kit — do not edit it! -->
<svelte:options runes={true} />
<script>
import { setContext, onMount, tick } from 'svelte';
import { browser } from '$app/environment';
// stores
...
I have provided this output to the example.
It's actually all over the place, sometimes working when revisiting the page during preview of prod build, but not during others. Fails completely when hosted by a cloudflare worker. Scratching my head on this one.
Edit: The first example randomly just started working, so I have posted a new example that should be more dependable. This uses adapter-auto and fails during the prerendering phase. Notably, the wasm generated files + executable are missing from the compilation output.
I'm not able to reproduce the same error logs when running build on the reproduction. Can you provide another minimal reproduction and a set of steps to run? These are the build logs I get:
x Build failed in 1.16s
error during build:
[vite:load-fallback] Could not load /home/chewteeming/github/svelte-bug-wasm-2/src/lib/wasm/pkg/frontend_wasm (imported by src/routes/+layout.svelte): ENOENT: no such file or directory, open '/home/chewteeming/github/svelte-bug-wasm-2/src/lib/wasm/pkg/frontend_wasm'
Error: Could not load /home/chewteeming/github/svelte-bug-wasm-2/src/lib/wasm/pkg/frontend_wasm (imported by src/routes/+layout.svelte): ENOENT: no such file or directory, open '/home/chewteeming/github/svelte-bug-wasm-2/src/lib/wasm/pkg/frontend_wasm'
ELIFECYCLE Command failed with exit code 1.
I'm not able to reproduce the same error logs when running build on the reproduction. Can you provide another minimal reproduction and a set of steps to run?
Absolutely! Apologies, had not added the README.md from the first example. For compilation, you'll want to install rust, but what I'll do is upload the wasm pkg file for this
Alright, should be available now. You should be able to reproduce this error just by running the build command (no rust compilation required). Thank you!
Edit:
I have also updated the readme with steps if you would like to compile the wasm binary directly. This requires the rust toolchain and the wasm host target. This can be added by running rustup target add wasm32-unknown-unknown
after installing the toolchain. Finally, run npm run build-wasm
, which will compile your binary + bindings out to $lib/pkg/
.
When running dev mode, it should run correctly.
When using adapter-auto
, it seems like it will prerender the page, causing compilation to fail during the build step. using a host adapter, like cloudflare
, it will succeed in compilation, but will render a 500 server error on page access on the first request. On occasion, the page may improperly load after the initial load, but not when running on cloudflare workers. I'm unsure about the other hosts, but will be doing more research today.
FOUND IT!! Did a lot of digging.
Edit: moved most of this comment to issue details
Last time I'm changing the title, wanted to make it more concise.
Describe the bug
On import of any function binding from WebAssembly will return an error not found when running a vite development build, due to usage of
vite-plugin-top-level-await
. This is a Sveltekit issue that appears upon usage of Svelte 5 over Svelte 4.Discovered behavior using the cloudflare adapter.
svelte-bug-wasm-2
reproduces the behavior with the auto adapter.Uses:
wasm-pack: 0.13.1
,vite-plugin-wasm: 3.3.0
for wasm bindingsReproduction
https://github.com/dsgallups/svelte-bug-wasmhttps://github.com/dsgallups/svelte-bug-wasm-2Branch with working compilation on svelte 4: https://github.com/dsgallups/svelte-bug-wasm-2/tree/svelte-4-working
Logs
System Info
Severity
blocking an upgrade
Additional Information
In
.svelte-kit/output/server/entries/pages/_layout.svelte.js
the following code is generated in svelte 4:Now, svelte-5 will generate:
The issue is that
__tla
doesn't complete before_layout
is called byrender
:_layout
is initially undefined. If called before__tla
resolves,component
(_layout
) in0.js
will return undefined leading all the way toPyramid[0]
being the component constructor for the layout page to be undefined. This is why it would sometimes work, because something would eventually process the topLevelAwait.Why does this work in Svelte 4?
in
internal.js
the Root function will validate thatconstructors[0]
andconstructors[1]
have been properly instantiated usingvalidate_component
inssr.js
. Svelte 4 has a fallback for this, so things work:Compared to the
Root
function from root.svelte in.svelte-kit/output/server/chunks/internal.js:~516
:Since these constructors are not validated in Svelte 5, that leads to the error.
This is why I believe wasm won't work: Top level await does not set the component before the component's render() function is called.
Why is this Important?
Because the ES Module Integration proposal for WASM is not supported, the vite docs recommend usage of the
vite-plugin-wasm
dep. Since Svelte cannot properly compile components that utilize this plugin, thewasm-pack
toolchain becomeseffectively uselessmore difficult to use.Examples of a workaround are not availableA half-workaround is to use a dynamic import. There are some cases, however, where wasm memory should be loaded alongside the constructor outside of an onMount callback.Idea for solution
I'd like to readd the
validate_component
/fallback functionality back to sveltekit in some form. However, I have no clue why it was removed. My hypothesis is that the simplest approach is to adjustwrite_root
with anif
check onconstructor[0]
, but not sure what a reasonable fallback would be. Some guidance on this would be super helpful!