cloudflare / cloudflare/workers-rs

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

Open
#736 5 comments 7 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
3.7k
Forks
429
Avg merge
20h 28m
Merged PRs (30d)
7

Description

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!

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.