-
-
Notifications
You must be signed in to change notification settings - Fork 692
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
Support wasm32-wasi target for SSR #295
Comments
ah yes, this is what was killing me :) very much interestingness! |
This is somewhat weird; when you're compiling for any other target I'm aware of, wasm-bindgen will compile but panic if you try to run it. I guess I haven't tried this before! It should be relatively easy to make the dependencies on wasm-bindgen and probably web-sys optional. Edit: Ahhh I see of course, CloudFlare Workers are running V8 which is why I haven't run into this before. |
yaya! I was trying to get leptos to run with spin and it would fail with the linked error :) |
Huh this is actually a much bigger issue than I would have thought. It is not just that let (name, set_name) = create_signal(cx, "The name is ThePrimeagen".to_string());
// this can't compile for WASI because we're not allowed to have `web-sys`
// and the type of `ev` is inferred to be `web_sys::InputEvent`
let on_change = move |ev| {
set_name(event_target_value(&ev));
};
view! { cx,
<input on:change=on_change type="text" value=name/>
} For normal targets, this compiles fine—it would panic if you tried to run the click handler on the server, but you obviously never do. With WASI/Spin, you compile but get
I could hypothetically create like a let (name, set_name) = create_signal(cx, "The name is ThePrimeagen".to_string());
// gross
#[cfg(not(feature = "wasi"))]
let on_change = move |ev| {
set_name(event_target_value(&ev));
};
// then I'd have to exclude on:change from the SSR code--fine
view! { cx,
<input on:change=on_change type="text" value=name/>
} There are basically four ways out of this:
Personally I think 3 or 4 is best. I have most of a PR for 2 but I think it's a pretty painful solution. |
Related: rustwasm/wasm-bindgen#2471 but doesn't seem like it will be solved anytime soon. Maybe a
|
Is it the responsibility to have this implementation on the view framework or the runner itself? let say, yew and sycamore have the same problem? Would the bindgen free implementation duplicated throughout this code bases? Would React or Svelte generate all the JS specific code, to run on a JS engine without this native support? |
Yew and Sycamore (and every other Rust/Wasm web framework I've seen) have an even worse version of the same problem: they use
I'm what the React/Svelte part of your question means.
Yeah it seems like a pretty fundamental problem if they want to support rendering any Rust frontend frameworks in a WASI environment. |
@gbj React/Svelte were just examples of JS frameworks, to illustrate the point what if nodejs didn't have the necessary infrastructure to support reactivity. Who would be responsible for the implementation? Maybe a bad example ;) |
Ah I see what you ean. Yeah, it's a little more like "Everyone knows you can't actually access Web APIs in NodeJS. But what if NodeJS did not allow your source JS files to contain any references to Web APIs (like DOM elements or events), even if you don't try to run them?" Yeah, then server-side rendering any meaningful app with Node would be impossible. |
Great news! The answer here is simpler than I thought: I know nothing about I don't know if you can pass this as an argument via Spin but it should resolve the issue for you. |
@gbj - I'd be surprised if this actually works though when running the module. If code attempts to call one of the wbg imports, the runtime will trap? that should stop execution. Were you able to run the module with this flag and see it behave the way you'd expect it to? |
@nilslice This is exactly my point: every Rust web framework that tries to handle frontend and backend code, is set up such that it can compile code that references In the Leptos case for example, #[component]
fn SimpleExample(cx: Scope) -> impl IntoView {
let (name, set_name) = create_signal(cx, "The name is ThePrimeagen".to_string());
let on_change = move |ev| { // ev is inferred to be `web_sys::MouseEvent`
set_name(event_target_value(&ev));
};
view! { cx,
<input on:change=on_change type="text" value=name/>
}
} The function The framework is set up to be able to compile |
for server rendering, if you want to run the wasm in a runner without v8 functionality, you would probably will need a wasm32-wasi target.
unfortunately, due to some dependencies, mostly wasm-bindgen, leptos code won't run, because of binds to JS specific imports.
The text was updated successfully, but these errors were encountered: