1
- use crate :: { cli:: * , AppBuilder , BuildRequest , Workspace , PROFILE_SERVER } ;
1
+ use crate :: { cli:: * , AppBuilder , BuildRequest , Workspace } ;
2
2
use crate :: { BuildMode , Platform } ;
3
- use target_lexicon:: Triple ;
4
3
5
- use super :: target:: { TargetArgs , TargetCmd } ;
4
+ use super :: target:: TargetArgs ;
6
5
7
6
/// Build the Rust Dioxus app and all of its assets.
8
7
///
@@ -16,42 +15,9 @@ pub struct BuildArgs {
16
15
#[ clap( long) ]
17
16
pub ( crate ) fullstack : Option < bool > ,
18
17
19
- /// The feature to use for the client in a fullstack app [default: "web"]
20
- #[ clap( long) ]
21
- pub ( crate ) client_features : Vec < String > ,
22
-
23
- /// The feature to use for the server in a fullstack app [default: "server"]
24
- #[ clap( long) ]
25
- pub ( crate ) server_features : Vec < String > ,
26
-
27
- /// Build with custom profile for the fullstack server
28
- #[ clap( long, default_value_t = PROFILE_SERVER . to_string( ) ) ]
29
- pub ( crate ) server_profile : String ,
30
-
31
- /// The target to build for the server.
32
- ///
33
- /// This can be different than the host allowing cross-compilation of the server. This is useful for
34
- /// platforms like Cloudflare Workers where the server is compiled to wasm and then uploaded to the edge.
35
- #[ clap( long) ]
36
- pub ( crate ) server_target : Option < Triple > ,
37
-
38
18
/// Arguments for the build itself
39
19
#[ clap( flatten) ]
40
20
pub ( crate ) build_arguments : TargetArgs ,
41
-
42
- /// A list of additional targets to build.
43
- ///
44
- /// Server and Client are special targets that integrate with `dx serve`, while `crate` is a generic.
45
- ///
46
- /// ```sh
47
- /// dx serve \
48
- /// client --target aarch64-apple-darwin \
49
- /// server --target wasm32-unknown-unknown \
50
- /// crate --target aarch64-unknown-linux-gnu --package foo \
51
- /// crate --target x86_64-unknown-linux-gnu --package bar
52
- /// ```
53
- #[ command( subcommand) ]
54
- pub ( crate ) targets : Option < TargetCmd > ,
55
21
}
56
22
57
23
pub struct BuildTargets {
@@ -60,6 +26,40 @@ pub struct BuildTargets {
60
26
}
61
27
62
28
impl BuildArgs {
29
+ fn default_client ( & self ) -> & TargetArgs {
30
+ & self . build_arguments
31
+ }
32
+
33
+ fn default_server ( & self , client : & BuildRequest ) -> Option < & TargetArgs > {
34
+ // Now resolve the builds that we need to.
35
+ // These come from the args, but we'd like them to come from the `TargetCmd` chained object
36
+ //
37
+ // The process here is as follows:
38
+ //
39
+ // - Create the BuildRequest for the primary target
40
+ // - If that BuildRequest is "fullstack", then add the client features
41
+ // - If that BuildRequest is "fullstack", then also create a BuildRequest for the server
42
+ // with the server features
43
+ //
44
+ // This involves modifying the BuildRequest to add the client features and server features
45
+ // only if we can properly detect that it's a fullstack build. Careful with this, since
46
+ // we didn't build BuildRequest to be generally mutable.
47
+ let default_server = client. enabled_platforms . contains ( & Platform :: Server ) ;
48
+
49
+ // Make sure we set the fullstack platform so we actually build the fullstack variant
50
+ // Users need to enable "fullstack" in their default feature set.
51
+ // todo(jon): fullstack *could* be a feature of the app, but right now we're assuming it's always enabled
52
+ //
53
+ // Now we need to resolve the client features
54
+ let fullstack = ( ( default_server || client. fullstack_feature_enabled ( ) )
55
+ || self . fullstack . unwrap_or ( false ) )
56
+ && self . fullstack != Some ( false ) ;
57
+
58
+ fullstack. then_some ( & self . build_arguments )
59
+ }
60
+ }
61
+
62
+ impl CommandWithPlatformOverrides < BuildArgs > {
63
63
pub async fn build ( self ) -> Result < StructuredOutput > {
64
64
tracing:: info!( "Building project..." ) ;
65
65
@@ -92,89 +92,30 @@ impl BuildArgs {
92
92
// do some logging to ensure dx matches the dioxus version since we're not always API compatible
93
93
workspace. check_dioxus_version_against_cli ( ) ;
94
94
95
- let mut server = None ;
95
+ let client_args = match & self . client {
96
+ Some ( client) => & client. build_arguments ,
97
+ None => self . shared . default_client ( ) ,
98
+ } ;
99
+ let client = BuildRequest :: new ( client_args, None , workspace. clone ( ) ) . await ?;
96
100
97
- let client = match self . targets {
98
- // A simple `dx serve` command with no explicit targets
99
- None => {
100
- // Now resolve the builds that we need to.
101
- // These come from the args, but we'd like them to come from the `TargetCmd` chained object
102
- //
103
- // The process here is as follows:
104
- //
105
- // - Create the BuildRequest for the primary target
106
- // - If that BuildRequest is "fullstack", then add the client features
107
- // - If that BuildRequest is "fullstack", then also create a BuildRequest for the server
108
- // with the server features
109
- //
110
- // This involves modifying the BuildRequest to add the client features and server features
111
- // only if we can properly detect that it's a fullstack build. Careful with this, since
112
- // we didn't build BuildRequest to be generally mutable.
113
- let client = BuildRequest :: new ( & self . build_arguments , workspace. clone ( ) ) . await ?;
114
- let default_server = client
115
- . enabled_platforms
116
- . iter ( )
117
- . any ( |p| * p == Platform :: Server ) ;
118
-
119
- // Make sure we set the fullstack platform so we actually build the fullstack variant
120
- // Users need to enable "fullstack" in their default feature set.
121
- // todo(jon): fullstack *could* be a feature of the app, but right now we're assuming it's always enabled
122
- //
123
- // Now we need to resolve the client features
124
- let fullstack = ( ( default_server || client. fullstack_feature_enabled ( ) )
125
- || self . fullstack . unwrap_or ( false ) )
126
- && self . fullstack != Some ( false ) ;
127
-
128
- if fullstack {
129
- let mut build_args = self . build_arguments . clone ( ) ;
130
- build_args. platform = Some ( Platform :: Server ) ;
131
-
132
- let _server = BuildRequest :: new ( & build_args, workspace. clone ( ) ) . await ?;
133
-
134
- // ... todo: add the server features to the server build
135
- // ... todo: add the client features to the client build
136
- // // Make sure we have a server feature if we're building a fullstack app
137
- if self . fullstack . unwrap_or_default ( ) && self . server_features . is_empty ( ) {
138
- return Err ( anyhow:: anyhow!( "Fullstack builds require a server feature on the target crate. Add a `server` feature to the crate and try again." ) . into ( ) ) ;
139
- }
140
-
141
- server = Some ( _server) ;
142
- }
143
-
144
- client
145
- }
146
-
147
- // A command in the form of:
148
- // ```
149
- // dx serve \
150
- // client --package frontend \
151
- // server --package backend
152
- // ```
153
- Some ( cmd) => {
154
- let mut client_args_ = None ;
155
- let mut server_args_ = None ;
156
- let mut cmd_outer = Some ( Box :: new ( cmd) ) ;
157
- while let Some ( cmd) = cmd_outer. take ( ) {
158
- match * cmd {
159
- TargetCmd :: Client ( cmd_) => {
160
- client_args_ = Some ( cmd_. inner ) ;
161
- cmd_outer = cmd_. next ;
162
- }
163
- TargetCmd :: Server ( cmd) => {
164
- server_args_ = Some ( cmd. inner ) ;
165
- cmd_outer = cmd. next ;
166
- }
167
- }
168
- }
169
-
170
- if let Some ( server_args) = server_args_ {
171
- server = Some ( BuildRequest :: new ( & server_args, workspace. clone ( ) ) . await ?) ;
172
- }
173
-
174
- BuildRequest :: new ( & client_args_. unwrap ( ) , workspace. clone ( ) ) . await ?
175
- }
101
+ let server_args = match & self . server {
102
+ Some ( server) => Some ( & server. build_arguments ) ,
103
+ None => self . shared . default_server ( & client) ,
176
104
} ;
177
105
106
+ let mut server = None ;
107
+ // If there is a server, make sure we output in the same directory as the client build so we use the server
108
+ // to serve the web client
109
+ if let Some ( server_args) = server_args {
110
+ // Copy the main target from the client to the server
111
+ let main_target = client. main_target . clone ( ) ;
112
+ let mut server_args = server_args. clone ( ) ;
113
+ // The platform in the server build is always set to Server
114
+ server_args. platform = Some ( Platform :: Server ) ;
115
+ server =
116
+ Some ( BuildRequest :: new ( & server_args, Some ( main_target) , workspace. clone ( ) ) . await ?) ;
117
+ }
118
+
178
119
Ok ( BuildTargets { client, server } )
179
120
}
180
121
}
0 commit comments