workers-rs icon indicating copy to clipboard operation
workers-rs copied to clipboard

Challenges with Wasm Compilation for Complex Apps: mio and getrandom Feature Conflicts

Open elasticdotventures opened this issue 7 months ago • 5 comments

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:

  1. mio Compilation Errors: Despite efforts to minimize Tokio's features (e.g., default-features = false, only enabling macros, and ensuring net and rt features are not part of the Wasm build via our crate's features), mio (e.g., v1.0.4) consistently fails to compile for wasm32-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 causing mio to be built with OS-specific networking components. We've tried feature-gating tokio, axum, sea-orm, and reqwest to strip down their Tokio usage for Wasm builds.

  2. getrandom Feature 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 adding getrandom (e.g., v0.2.x) as a direct optional dependency with its js feature enabled, and activating this via a top-level feature for the Wasm build. cargo tree analysis reveals that other versions of getrandom (e.g., v0.3.x) are pulled in by transitive dependencies (like ahash via sqlx-core), often with getrandom's default features, which do not include js. This leads to the v0.3.x instance failing.

Attempts to Resolve:

  • Extensive use of default-features = false on 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 getrandom as a direct optional dependency with the js feature enabled for Wasm builds.
  • Ensuring clang is available for crates like ring.

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, and getrandom (and their users like sqlx, reqwest) in a complex dependency graph when targeting wasm32-unknown-unknown for workers-rs?
  • Are there common patterns or known workarounds for ensuring that all instances of getrandom correctly use the js feature, and that mio is compiled without its OS-specific parts?
  • Is there a more robust way to prevent tokio's net feature (and thus mio'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!

elasticdotventures avatar May 29 '25 01:05 elasticdotventures

I ran into the exact same problem and it is preventing me from upgrading to v0.6.0

cowlicks avatar Jul 10 '25 15:07 cowlicks

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.

jongiddy avatar Jul 21 '25 15:07 jongiddy

I tried version 0.6.1 but no longer have this issue.

cowlicks avatar Jul 29 '25 19:07 cowlicks

(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

mfreeborn avatar Aug 13 '25 22:08 mfreeborn

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.

guybedford avatar Oct 31 '25 01:10 guybedford