From 761c9503fdc06c3b5dac5d147747d44175cdffa2 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Wed, 14 Jan 2026 23:24:18 +0000 Subject: [PATCH] CLI: don't enable default features in `--no-default-features` builds (#5147) * Don't push default features in `--no-default-features` builds Signed-off-by: Nico Burns * add tests for default features and no default features outside of renderers --------- Signed-off-by: Nico Burns Co-authored-by: Evan Almloff --- Cargo.lock | 14 ++++++++++++ .../Cargo.toml | 16 ++++++++++++++ .../src/main.rs | 3 +++ .../Cargo.toml | 16 ++++++++++++++ .../src/main.rs | 3 +++ packages/cli/src/build/request.rs | 19 ++++++---------- packages/cli/src/test_harnesses.rs | 22 ++++++++++++++++++- 7 files changed, 80 insertions(+), 13 deletions(-) create mode 100644 packages/cli-harnesses/harness-web-with-default-features/Cargo.toml create mode 100644 packages/cli-harnesses/harness-web-with-default-features/src/main.rs create mode 100644 packages/cli-harnesses/harness-web-with-no-default-features/Cargo.toml create mode 100644 packages/cli-harnesses/harness-web-with-no-default-features/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 5667f8dab..c5b19cef5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9017,6 +9017,20 @@ dependencies = [ "dioxus", ] +[[package]] +name = "harness-web-with-default-features" +version = "0.0.1" +dependencies = [ + "dioxus", +] + +[[package]] +name = "harness-web-with-no-default-features" +version = "0.0.1" +dependencies = [ + "dioxus", +] + [[package]] name = "hash32" version = "0.2.1" diff --git a/packages/cli-harnesses/harness-web-with-default-features/Cargo.toml b/packages/cli-harnesses/harness-web-with-default-features/Cargo.toml new file mode 100644 index 000000000..e03d6e9ad --- /dev/null +++ b/packages/cli-harnesses/harness-web-with-default-features/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "harness-web-with-default-features" +version = "0.0.1" +edition = "2021" +license = "MIT OR Apache-2.0" +publish = false + +[dependencies] +dioxus = { workspace = true } + + +[features] +default=["other"] +other=[] + + \ No newline at end of file diff --git a/packages/cli-harnesses/harness-web-with-default-features/src/main.rs b/packages/cli-harnesses/harness-web-with-default-features/src/main.rs new file mode 100644 index 000000000..e7a11a969 --- /dev/null +++ b/packages/cli-harnesses/harness-web-with-default-features/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/packages/cli-harnesses/harness-web-with-no-default-features/Cargo.toml b/packages/cli-harnesses/harness-web-with-no-default-features/Cargo.toml new file mode 100644 index 000000000..572383fe0 --- /dev/null +++ b/packages/cli-harnesses/harness-web-with-no-default-features/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "harness-web-with-no-default-features" +version = "0.0.1" +edition = "2021" +license = "MIT OR Apache-2.0" +publish = false + +[dependencies] +dioxus = { workspace = true } + + +[features] +default=["other"] +other=[] + + \ No newline at end of file diff --git a/packages/cli-harnesses/harness-web-with-no-default-features/src/main.rs b/packages/cli-harnesses/harness-web-with-no-default-features/src/main.rs new file mode 100644 index 000000000..e7a11a969 --- /dev/null +++ b/packages/cli-harnesses/harness-web-with-no-default-features/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/packages/cli/src/build/request.rs b/packages/cli/src/build/request.rs index c5c9c741f..1fd53edd5 100644 --- a/packages/cli/src/build/request.rs +++ b/packages/cli/src/build/request.rs @@ -605,7 +605,7 @@ impl BuildRequest { Fullstack usage is inferred from the presence of the fullstack feature or --fullstack. */ let mut features = args.features.clone(); - let mut no_default_features = args.no_default_features; + let no_default_features = args.no_default_features; let all_features = args.all_features; let mut triple = args.target.clone(); let mut renderer = args.renderer; @@ -706,7 +706,6 @@ impl BuildRequest { renderer = renderer.or(Some(Renderer::Web)); bundle_format = bundle_format.or(Some(BundleFormat::Web)); triple = triple.or(Some("wasm32-unknown-unknown".parse()?)); - no_default_features = true; } Platform::MacOS => { if main_package.features.contains_key("desktop") && renderer.is_none() { @@ -715,7 +714,6 @@ impl BuildRequest { renderer = renderer.or(Some(Renderer::Webview)); bundle_format = bundle_format.or(Some(BundleFormat::MacOS)); triple = triple.or(Some(Triple::host())); - no_default_features = true; } Platform::Windows => { if main_package.features.contains_key("desktop") && renderer.is_none() { @@ -724,7 +722,6 @@ impl BuildRequest { renderer = renderer.or(Some(Renderer::Webview)); bundle_format = bundle_format.or(Some(BundleFormat::Windows)); triple = triple.or(Some(Triple::host())); - no_default_features = true; } Platform::Linux => { if main_package.features.contains_key("desktop") && renderer.is_none() { @@ -733,7 +730,6 @@ impl BuildRequest { renderer = renderer.or(Some(Renderer::Webview)); bundle_format = bundle_format.or(Some(BundleFormat::Linux)); triple = triple.or(Some(Triple::host())); - no_default_features = true; } Platform::Ios => { if main_package.features.contains_key("mobile") && renderer.is_none() { @@ -741,7 +737,6 @@ impl BuildRequest { } renderer = renderer.or(Some(Renderer::Webview)); bundle_format = bundle_format.or(Some(BundleFormat::Ios)); - no_default_features = true; match device.is_some() { // If targeting device, we want to build for the device which is always aarch64 true => triple = triple.or(Some("aarch64-apple-ios".parse()?)), @@ -762,7 +757,6 @@ impl BuildRequest { renderer = renderer.or(Some(Renderer::Webview)); bundle_format = bundle_format.or(Some(BundleFormat::Android)); - no_default_features = true; // maybe probe adb? if let Some(_device_name) = device.as_ref() { @@ -792,7 +786,6 @@ impl BuildRequest { renderer = renderer.or(Some(Renderer::Server)); bundle_format = bundle_format.or(Some(BundleFormat::Server)); triple = triple.or(Some(Triple::host())); - no_default_features = true; } Platform::Liveview => { if main_package.features.contains_key("liveview") && renderer.is_none() { @@ -801,12 +794,12 @@ impl BuildRequest { renderer = renderer.or(Some(Renderer::Liveview)); bundle_format = bundle_format.or(Some(BundleFormat::Server)); triple = triple.or(Some(Triple::host())); - no_default_features = true; } } - // If no default features are enabled, we need to add the rendererless features - if no_default_features { + // If default features are enabled, we need to add the default features + // which don't enable a renderer + if !no_default_features { features.extend(Self::rendererless_features(main_package)); features.dedup(); features.sort(); @@ -987,7 +980,9 @@ impl BuildRequest { Ok(Self { features, bundle, - no_default_features, + // We hardcode passing `--no-default-features` to Cargo because dx manually enables + // the default features we want. + no_default_features: true, all_features, crate_package, crate_target, diff --git a/packages/cli/src/test_harnesses.rs b/packages/cli/src/test_harnesses.rs index 7f08494f0..e1606102c 100644 --- a/packages/cli/src/test_harnesses.rs +++ b/packages/cli/src/test_harnesses.rs @@ -255,7 +255,27 @@ async fn test_harnesses() { let server = t.server.unwrap(); assert_eq!(server.bundle, BundleFormat::Server); assert_eq!(server.triple, Triple::host()); - }) + }), + TestHarnessBuilder::new("harness-web-with-no-default-features") + .deps(r#"dioxus = { workspace = true }"#) + .fetr(r#"default=["other"]"#) + .fetr(r#"other=[]"#) + .asrt(r#"dx build --no-default-features --web"#, |targets| async move { + let t = targets.unwrap(); + assert_eq!(t.client.bundle, BundleFormat::Web); + assert_eq!(t.client.features, vec!["dioxus/web"]); + assert!(t.server.is_none()); + }), + TestHarnessBuilder::new("harness-web-with-default-features") + .deps(r#"dioxus = { workspace = true }"#) + .fetr(r#"default=["other"]"#) + .fetr(r#"other=[]"#) + .asrt(r#"dx build --web"#, |targets| async move { + let t = targets.unwrap(); + assert_eq!(t.client.bundle, BundleFormat::Web); + assert_eq!(t.client.features.iter().map(|s| s.as_str()).collect::>(), ["dioxus/web", "other"].into_iter().collect::>()); + assert!(t.server.is_none()); + }), ]) .await; }