Reputation: 672
I have a crate lib
that contains tons of structs and impls. Then I have another one called web
that will make the portability of the core lib
to the web. There is also api
in case I want the app to be server-side.
myproject-api
myproject-lib
myproject-web
What I don't want is to add all the wasm
dependencies to lib
, only in the web
project and expose parts of the main library to the web. Is it possible to #[wasm_bindgen]
the structs defined in the myproject-lib
in myproject-web
?
Upvotes: 10
Views: 2490
Reputation: 59912
Not directly. The #[wasm_bindgen]
attribute relies on being able to parse the struct and impls in order to generate the bindings. You would have to create wrapper types and functions for the attribute to bind to.
Say your myproject-lib
looks like:
pub struct MyStruct {
pub foo: i32,
}
impl MyStruct {
pub fn bar(&self) {
// do something
}
}
The bindings would be implemented in myproject-web
like:
use myproject_lib::*;
use wasm_bindgen::prelude::*;
#[wasm_bindgen(js_name = MyStruct)]
pub struct MyStructWrapper(MyStruct);
#[wasm_bindgen(js_class = MyStruct)]
impl MyStructWrapper {
#[wasm_bindgen(getter)]
pub fn foo(&self) -> i32 {
self.0.foo
}
#[wasm_bindgen(setter)]
pub fn set_foo(&mut self, value: i32) {
self.0.foo = value;
}
pub fn bar(&self) {
self.0.bar();
}
}
As you can see, everything is done very explicitly.
js_name
and js_class
I believe the more widely-used method is to add the bindings to the original library but only enabled by a feature. This avoids much duplication, is less of a headache to implement, and ensures the bindings are always in-sync.
Add a "wasm"
feature that adds wasm-bindgen
as an opt-in a dependency in your Cargo.toml
:
[features]
wasm = ["wasm-bindgen"]
[dependencies]
wasm-bindgen = { version = "X.X.X", optional = true }
Then you can use cfg
and cfg_attr
to only enable the wasm_bindgen
attributes when the feature is enabled:
#[cfg(feature = "wasm")]
use wasm_bindgen::prelude::*;
#[cfg_attr(feature = "wasm", wasm_bindgen)]
pub struct MyStruct {
pub foo: i32,
}
#[cfg_attr(feature = "wasm", wasm_bindgen)]
impl MyStruct {
pub fn bar(&self) {
// do something
}
}
Upvotes: 12