Challenges with Wasm Compilation for Complex Apps: mio and getrandom Feature Conflicts
Hi workers-rs team and community,
We're encountering persistent challenges when attempting to compile a moderately complex Rust application for the wasm32-unknown-unknown target for use with Cloudflare Workers. The application uses a stack similar to Axum for routing, Tokio (primarily for its macros and types, not necessarily its full runtime in the worker), an ORM like SeaORM (with SQLx), and HTTP clients like Reqwest (e.g., via OpenIDConnect).
Core Issues:
-
mioCompilation Errors: Despite efforts to minimize Tokio's features (e.g.,default-features = false, only enablingmacros, and ensuringnetandrtfeatures are not part of the Wasm build via our crate's features),mio(e.g.,v1.0.4) consistently fails to compile forwasm32-unknown-unknown, citing: `compile_error!("This wasm target is unsupported by mio. If using Tokio, disable the net feature.");` This suggests that some part of the dependency graph is still causingmioto be built with OS-specific networking components. We've tried feature-gatingtokio,axum,sea-orm, andreqwestto strip down their Tokio usage for Wasm builds. -
getrandomFeature Conflicts: We encounter errors like: `error: The wasm32-unknown-unknown targets are not supported by default; you may need to enable the "wasm_js" configuration flag.` This occurs even when addinggetrandom(e.g.,v0.2.x) as a direct optional dependency with itsjsfeature enabled, and activating this via a top-level feature for the Wasm build.cargo treeanalysis reveals that other versions ofgetrandom(e.g.,v0.3.x) are pulled in by transitive dependencies (likeahashviasqlx-core), often withgetrandom's default features, which do not includejs. This leads to thev0.3.xinstance failing.
Attempts to Resolve:
- Extensive use of
default-features = falseon direct dependencies (tokio,axum,sea-orm,reqwest,openidconnect,rand,jsonwebtoken,ahash,uuid). - Careful feature selection for these crates when building for Wasm vs. native.
- Adding
getrandomas a direct optional dependency with thejsfeature enabled for Wasm builds. - Ensuring
clangis available for crates likering.
Example Scenario (Conceptual Cargo.toml structure):
```toml
[dependencies]
tokio = { version = "1", default-features = false, features = ["macros"] }
axum = { version = "0.7", default-features = false, features = ["macros", /* other non-tokio-net features */] }
sea-orm = { version = "0.12", default-features = false, features = ["macros", "sqlx-sqlite"] } # sqlx-sqlite for local, minimal for wasm
reqwest = { version = "0.11", default-features = false, features = ["json"] } # Wasm uses fetch
openidconnect = { version = "3.5", default-features = false, features = ["reqwest"] }
getrandom = { version = "0.2", optional = true, features = ["js"] }
worker = { version = "0.0.19", optional = true } # Using the 'worker' crate for workers-rs
... other crypto, utility crates
[features]
default = [
"tokio/rt-multi-thread", "tokio/net",
"sea-orm/runtime-tokio-rustls", "sea-orm/sqlx-postgres",
"reqwest/rustls-tls", # Native TLS for reqwest
"axum/tokio" # Axum with Tokio for native server
]
cloudflare = [
"dep:worker", "dep:console_error_panic_hook", "dep:getrandom"
# No tokio/net, no axum/tokio, no sea-orm runtime features
]
```
Questions/Request for Guidance:
- What are the recommended best practices for managing features of
tokio,mio, andgetrandom(and their users likesqlx,reqwest) in a complex dependency graph when targetingwasm32-unknown-unknownforworkers-rs? - Are there common patterns or known workarounds for ensuring that all instances of
getrandomcorrectly use thejsfeature, and thatmiois compiled without its OS-specific parts? - Is there a more robust way to prevent
tokio'snetfeature (and thusmio's problematic parts) from being activated by transitive dependencies in a Wasm build?
Any insights or advice on structuring Cargo.toml features for such scenarios would be greatly appreciated. We understand that Wasm builds with large ecosystems can be tricky, and we're looking for ways to make this more manageable.
Thank you!
I ran into the exact same problem and it is preventing me from upgrading to v0.6.0
Can you run cargo tree -e features mio to identify which crate is still enabling mio/net? If it is tokio/net then repeat using, for example, cargo tree -e features tokio to find the dependency chain up to a dependency that you control. You need to remove the dependency (or its feature) that ultimately enables mio/net.
I tried version 0.6.1 but no longer have this issue.
(EDIT: actually it works when I use RUSTFLAGS='--cfg getrandom_backend="wasm_js"' npx wrangler dev to build)
I'm getting this on 0.6.1 running the vanilla tokio-postgres example - compilation fails with complaints from getrandom.
Rust version: 1.89.0
Wrangler version: 4.29.1
getrandom has again changed its support approach in https://github.com/wasm-bindgen/wasm-bindgen/issues/4667. Now the getrandom_backend="wasm_js" no longer needs to be set via options, and only the wasm_js feature needs to be enabled for it.