-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Deprecate JsValue::from_serde
and JsValue::into_serde
#3031
Conversation
I've listed `serde-wasm-bindgen` as the replacement, and changed the section of the guide that talks about Serde to talk about `serde-wasm-bindgen` instead of the deprecated methods. I didn't remove it entirely because I can imagine someone remembering it and trying to look it back up, only to find that it no longer exists, which would quite frustrating. I also added a footnote about the deprecated methods in case someone remembers the old way and wants to know what happened. There were several examples using `from_serde`/`into_serde`, which I updated to use `serde-wasm-bindgen` or not use `serde` altogether. The `fetch` example was a bit weird, in that it took a JS value, parsed it into a Rust value, only to serialize it back into a JS value. I removed that entirely in favour of just passing the original JS value directly. I suppose it behaves slightly differently in that it loses the extra validation, but a panic isn't all that much better than a JS runtime error.
Whether As a data point, in our use case (a parser module compiled to WebAssembly, passing an AST to the JavaScript side) we went the opposite way, dropping pub fn parse(formula: &str) -> JsValue {
- let serializer = serde_wasm_bindgen::Serializer::new().serialize_maps_as_objects(true);
match native_parse(formula) {
Ok(result) => {
- result.serialize(&serializer).unwrap_or_else(|err| {
+ JsValue::from_serde(&result).unwrap_or_else(|err| { and this significantly reduced per-parse call overhead; we saw our measured parse times on real-world data (measured in Node.js 16.x) change from:
to:
This is presumably because a structure of potentially many JS objects is returned, which gets chatty over the JS/WebAssembly boundary in the So the comment “This approach [ Plus So, you know, not thrilled about this idea. :-) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would agree that serde-wasm-bindgen
is a bit of a different use case than the methods deprecated here so I don't think it's a direct replacement. Instead though could the __wbindgen_json_{parse,serialize}
methods be exposed as first-class methods perhaps? That would give convenient access to JSON
and additionally be able to lift the serde dependency up in to callers instead of baking it in wasm-bindgen
itself.
@alexcrichton I've started this PR rustwasm/gloo#242 to extract this functionality. If |
As far as I understand it, |
Indeed! In that case I think it would be good to migrate the examples to that instead and to mention that as an alternative in addition to |
@hamza1311 I think they slightly different: in my PR for gloo, when I passed |
Looks like the intrinsic has a special case for wasm-bindgen/crates/cli-support/src/js/mod.rs Lines 3446 to 3453 in f197b0e
That should be able to be replicated in gloo pretty easily. |
@hamza1311 |
@Liamolucko would you be up for rewording to indicate that |
Okay, I've added a section to the guide page which talks about using JSON as an alternative to In my opinion, Also, I ran |
I was considering leaving the examples using `JSON` directly and mentioning `gloo-utils` as an aside, but that has the major footgun that `JSON.stringify(undefined) === undefined`, causing a panic when deserializing `undefined` since the return type of `JSON::stringify` isn't optional. `gloo-utils` works around this, so I recommended it instead.
`serde_json`. This caused problems when certain features of `serde_json` and | ||
other crates were enabled that caused it to depend on `wasm-bindgen`, creating | ||
a circular dependency, which is illegal in Rust and caused people's code to | ||
fail to compile. So, they were deprecated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The functions in this crate were deprecated, but the usage isn't really deprecated (just no longer the recommended default, and requires a trait from a different crate), so maybe
fail to compile. So, they were deprecated. | |
fail to compile. So, they were moved out of `wasm-bindgen` into `gloo_utils` to | |
resolve the circular dependency and replaced by `serde-wasm-bindgen` as the | |
default approach to use. |
... or something like that.
src/lib.rs
Outdated
@@ -214,6 +221,7 @@ impl JsValue { | |||
/// | |||
/// Returns any error encountered when serializing `T` into JSON. | |||
#[cfg(feature = "serde-serialize")] | |||
#[deprecated = "causes dependency cycles, use `serde-wasm-bindgen` instead"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#[deprecated = "causes dependency cycles, use `serde-wasm-bindgen` instead"] | |
#[deprecated = "causes dependency cycles, use `serde-wasm-bindgen` instead, or `gloo_utils::format::JsValueSerdeExt`"] |
src/lib.rs
Outdated
@@ -201,6 +201,13 @@ impl JsValue { | |||
/// Creates a new `JsValue` from the JSON serialization of the object `t` | |||
/// provided. | |||
/// | |||
/// **This function is deprecated**, due to [creating a dependency cycle in | |||
/// some circumstances][dep-cycle-issue]. Use [`serde-wasm-bindgen`] | |||
/// instead, or manually call `serde_json::to_string` + `JSON.parse`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// instead, or manually call `serde_json::to_string` + `JSON.parse`. | |
/// instead, or `gloo_utils::format::JsValueSerdeExt`, or manually call | |
/// `serde_json::to_string` + `JSON.parse`. |
src/lib.rs
Outdated
@@ -225,6 +233,13 @@ impl JsValue { | |||
/// Invokes `JSON.stringify` on this value and then parses the resulting | |||
/// JSON into an arbitrary Rust value. | |||
/// | |||
/// **This function is deprecated**, due to [creating a dependency cycle in | |||
/// some circumstances][dep-cycle-issue]. Use [`serde-wasm-bindgen`] | |||
/// instead, or manually call `JSON.stringify` + `serde_json::from_str`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// instead, or manually call `JSON.stringify` + `serde_json::from_str`. | |
/// instead, or `gloo_utils::format::JsValueSerdeExt`, or manually call | |
/// `JSON.stringify` + `serde_json::from_str`. |
src/lib.rs
Outdated
@@ -236,6 +251,7 @@ impl JsValue { | |||
/// | |||
/// Returns any error encountered when parsing the JSON into a `T`. | |||
#[cfg(feature = "serde-serialize")] | |||
#[deprecated = "causes dependency cycles, use `serde-wasm-bindgen` instead"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#[deprecated = "causes dependency cycles, use `serde-wasm-bindgen` instead"] | |
#[deprecated = "causes dependency cycles, use `serde-wasm-bindgen` instead, or `gloo_utils::format::JsValueSerdeExt`"] |
Just to add some clarification not reflected in graph titles - after various added optimisations over time, serde-wasm-bindgen should be faster than serde-json based approach for almost all cases, except when your data has a lot of strings. Not much more we can do there, as having all strings serialized into one large string (JSON) on one side, passing that string once, and parsing it back on another side will be always faster than passing tons of small strings one-by-one (same overhead x N). For other data types we can do a lot better than JSON though, and that's why twitter benchmark (lots of strings) looks so different than others. UPD / side-note: I see the original comment mentions lots of small objects and yeah, I can see how that case would have similar overhead issues to having lots of strings. |
1. Reorganize dependencies and remove requirements ("=") on wasm-bindgen and js-sys, due to conflicts that can occur when using this crate. 2. Replace wasm-bindgen's "serde-serialize" feature with serde-wasm-bindgen due to cyclical dependency issue. Relates to: tkaitchuck/aHash#95 rustwasm/wasm-bindgen#3031
1. Reorganize dependencies and remove requirements ("=") on wasm-bindgen and js-sys, due to conflicts that can occur when using this crate. 2. Replace wasm-bindgen's "serde-serialize" feature with serde-wasm-bindgen due to cyclical dependency issue. Relates to: tkaitchuck/aHash#95 rustwasm/wasm-bindgen#3031
|
||
`serde-wasm-bindgen` works by directly manipulating JavaScript values. This | ||
requires a lot of calls back and forth between Rust and JavaScript, which can | ||
sometimes be slow. An alternative way of doing this is to serialize values to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like it's important to still call out the limitations in terms of type support in JSON-based approach here too (like the document did in the original version).
The new version of this section makes it sound like both approaches are equivalent and the only difference is performance. However, the support for various JavaScript types that are not representable by JSON is an even more important advantage of serde-wasm-bindgen than just runtime perf or code size IMO.
sometimes be slow. An alternative way of doing this is to serialize values to | ||
JSON, and then parse them on the other end. Browsers' JSON implementations are | ||
usually quite fast, and so this approach can outstrip `serde-wasm-bindgen`'s | ||
performance in some cases. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
performance in some cases. | |
performance in some cases. But this approach supports only types that can be | |
serialized as JSON, leaving out some important types that `serde-wasm-bindgen` | |
supports such as `Map`, `Set`, and array buffers. |
... addressing @RReverser's point about type support
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, so this edit didn't get in? Can you make a separate PR please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Voilà! #3047
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great to me, thanks again! I think further iteration is safe to happen in-tree
…8080) The `serde-serialize` feature is deprecated (rustwasm/wasm-bindgen#3031). This solves a cyclic dependency error with aHash
…alize feature Summary: `wasm-bindgen`s `serde-serialize` feature is the cause of: > cyclic package dependency: package indexmap v1.8.0 depends on itself See https://fb.workplace.com/groups/rust.language/posts/9594592340589295/ This diff updates `wasm-bindgen` to 0.2.83, which deprecates the `serde-serialize` feature in favor of the `serde-wasm-bindgen` create (see rustwasm/wasm-bindgen#3031) Reviewed By: diliop Differential Revision: D40104867 fbshipit-source-id: 9396923fba95ff7919c9a751b6a76c407934b9e4
I'm still seeing this issue after updating wasm-bindgen to latest 0.2.84. On the error below I can see wasm-bindgen on latest version 0.2.84. Also js-sys on latest 0.3.61 which consumes wasm-bindgen 0.2.84.
|
Did you remove the |
@RReverser I did not have the Is there a way to force indirect dependencies not using Thanks! |
For anyone that might find this helpful, you can run |
@tomasro27 FWIW for slightly simpler way you could also do |
Serde-serialize is deprecated, see rustwasm/wasm-bindgen#3031. This fix is required to prevent circular dependencies, see rust-random/getrandom#231 Fixes seanmonstar#2155
* Moved deprecated .cargo/config to config.toml * Ignore clippy warning * Updated body_reader and channel dependencies * Updated config-wasm and hdr-histogram dependencies * Updated additional dependencies - Held back hyper, http, and yansi due to major changes * Updated Yansi to latest version - Converted Paint::disable to Yansi::disable - Removed Windows specific code. Yansi now will try to enable on Windows and automatically disables if it can't activate. * Added build test-server to the PR script and workflow * Fix dependency loop with ahash on itself - tkaitchuck/aHash#95 (comment) - rustwasm/wasm-bindgen#3031 (comment) * Updated yaml-rust to use yaml-rust2 due to deprecation - chyh1990/yaml-rust#197 - chyh1990/yaml-rust#160 (comment) * Updated cargo deny to remove deprecated entries - EmbarkStudios/cargo-deny#611 - https://embarkstudios.github.io/cargo-deny/checks/licenses/cfg.html#the-clarify-field-optional * Updated cargo lock file * Updated code for deprecations - Added tests for create_date_diff, then updated deprecated calls and confirmed tests still passed * Added clippy ignore large results and errors * Fixed tests to validate to UTC - Since the PR flow runs on UTC, updated the local PR script to also run UTC - Updated the create_date_diff test to validate UTC and print a warning to run UTC if it fails
* Moved deprecated .cargo/config to config.toml * Ignore clippy warning * Updated body_reader and channel dependencies * Updated config-wasm and hdr-histogram dependencies * Updated additional dependencies - Held back hyper, http, and yansi due to major changes * Updated Yansi to latest version - Converted Paint::disable to Yansi::disable - Removed Windows specific code. Yansi now will try to enable on Windows and automatically disables if it can't activate. * Added build test-server to the PR script and workflow * Fix dependency loop with ahash on itself - tkaitchuck/aHash#95 (comment) - rustwasm/wasm-bindgen#3031 (comment) * Updated yaml-rust to use yaml-rust2 due to deprecation - chyh1990/yaml-rust#197 - chyh1990/yaml-rust#160 (comment) * Updated cargo deny to remove deprecated entries - EmbarkStudios/cargo-deny#611 - https://embarkstudios.github.io/cargo-deny/checks/licenses/cfg.html#the-clarify-field-optional * Updated cargo lock file * Updated code for deprecations - Added tests for create_date_diff, then updated deprecated calls and confirmed tests still passed * Added clippy ignore large results and errors * Fixed tests to validate to UTC - Since the PR flow runs on UTC, updated the local PR script to also run UTC - Updated the create_date_diff test to validate UTC and print a warning to run UTC if it fails
I've listed
serde-wasm-bindgen
as the replacement, and changed the section of the guide that talks about Serde to talk aboutserde-wasm-bindgen
instead of the deprecated methods.I didn't remove it entirely because I can imagine someone remembering it and trying to look it back up, only to find that it no longer exists, which would quite frustrating. I also added a footnote about the deprecated methods in case someone remembers the old way and wants to know what happened.
There were several examples using
from_serde
/into_serde
, which I updated to useserde-wasm-bindgen
or not useserde
altogether.The
fetch
example was a bit weird, in that it took a JS value, parsed it into a Rust value, only to serialize it back into a JS value. I removed that entirely in favour of just passing the original JS value directly. I suppose it behaves slightly differently in that it loses the extra validation, but a panic isn't all that much better than a JS runtime error.Fixes #2770
Fixes tkaitchuck/aHash#95
This also indirectly 'fixes' issues about the deprecated functions:
Resolves #1258
Resolves #2017
Resolves #2539