Restore SSG serve logic (#4111)

* Build ssg routes when both the client and server builds are finished

* Fix default server fn encoding

* fix tokio console

* fix ssg

* add prerendering message

* render under the same environment variables as normal

* fix check

* use should_bundle_to_asset

* enable ssg playwright test

* fix clippy
This commit is contained in:
Evan Almloff authored and GitHub committed 2025-06-23 13:35:46 -07:00
1 parent f610c6b8c1
commit fdd77d79c1
17 files changed
+357 -236

No files matched your search

+4 -1
View File
@@ -126,6 +126,9 @@ pub(crate) async fn serve_all(args: ServeArgs, tracer: &mut TraceController) ->
// And then update the websocketed clients with the new build status in case they want it
devserver.new_build_update(&update).await;
// Start the SSG build if we need to
builder.new_build_update(&update, &devserver).await;
// And then open the app if it's ready
match update {
BuilderUpdate::Progress { .. } => {}
@@ -161,7 +164,7 @@ pub(crate) async fn serve_all(args: ServeArgs, tracer: &mut TraceController) ->
}
BuildMode::Base | BuildMode::Fat => {
_ = builder
.open(bundle, &mut devserver)
.open(&bundle, &mut devserver)
.await
.inspect_err(|e| tracing::error!("Failed to open app: {}", e));
}
+1
View File
@@ -550,6 +550,7 @@ impl Output {
BuildStage::Linking => lines.push("Linking".yellow()),
BuildStage::Hotpatching => lines.push("Hot-patching...".yellow()),
BuildStage::ExtractingAssets => lines.push("Extracting assets".yellow()),
BuildStage::Prerendering => lines.push("Pre-rendering...".yellow()),
_ => {}
};
+38 -5
View File
@@ -1,8 +1,8 @@
use super::{AppBuilder, ServeUpdate, WebServer};
use crate::{
platform_override::CommandWithPlatformOverrides, BuildArtifacts, BuildId, BuildMode,
BuildTargets, Error, HotpatchModuleCache, Platform, Result, ServeArgs, TailwindCli, TraceSrc,
Workspace,
BuildTargets, BuilderUpdate, Error, HotpatchModuleCache, Platform, Result, ServeArgs,
TailwindCli, TraceSrc, Workspace,
};
use anyhow::Context;
use dioxus_core::internal::{
@@ -66,6 +66,7 @@ pub(crate) struct AppServer {
pub(crate) _wsl_file_poll_interval: u16,
pub(crate) always_on_top: bool,
pub(crate) fullstack: bool,
pub(crate) ssg: bool,
pub(crate) watch_fs: bool,
// resolve args related to the webserver
@@ -138,6 +139,7 @@ impl AppServer {
let (watcher_tx, watcher_rx) = futures_channel::mpsc::unbounded();
let watcher = create_notify_watcher(watcher_tx.clone(), wsl_file_poll_interval as u64);
let ssg = args.platform_args.shared.targets.ssg;
let target_args = CommandWithPlatformOverrides {
shared: args.platform_args.shared.targets,
server: args.platform_args.server.map(|s| s.targets),
@@ -150,7 +152,7 @@ impl AppServer {
let fullstack = server.is_some();
let should_proxy_port = match client.platform {
Platform::Server => true,
_ => fullstack,
_ => fullstack && !ssg,
};
let proxied_port = should_proxy_port
@@ -204,6 +206,7 @@ impl AppServer {
_force_sequential: force_sequential,
cross_origin_policy,
fullstack,
ssg,
tw_watcher,
server_args,
client_args,
@@ -226,6 +229,27 @@ impl AppServer {
Ok(runner)
}
pub(crate) async fn rebuild_ssg(&mut self, devserver: &WebServer) {
if self.client.stage != BuildStage::Success {
return;
}
// Run SSG and cache static routes if the server build is done
if let Some(server) = self.server.as_mut() {
if !self.ssg || server.stage != BuildStage::Success {
return;
}
if let Err(err) = crate::pre_render_static_routes(
Some(devserver.devserver_address()),
server,
Some(&server.tx.clone()),
)
.await
{
tracing::error!("Failed to pre-render static routes: {err}");
}
}
}
pub(crate) async fn wait(&mut self) -> ServeUpdate {
let client = &mut self.client;
let server = self.server.as_mut();
@@ -294,6 +318,14 @@ impl AppServer {
}
}
/// Handle an update from the builder
pub(crate) async fn new_build_update(&mut self, update: &BuilderUpdate, devserver: &WebServer) {
if let BuilderUpdate::BuildReady { .. } = update {
// If the build is ready, we need to check if we need to pre-render with ssg
self.rebuild_ssg(devserver).await;
}
}
/// Handle the list of changed files from the file watcher, attempting to aggressively prevent
/// full rebuilds by hot-reloading RSX and hot-patching Rust code.
///
@@ -488,7 +520,7 @@ impl AppServer {
/// Finally "bundle" this app and return a handle to it
pub(crate) async fn open(
&mut self,
artifacts: BuildArtifacts,
artifacts: &BuildArtifacts,
devserver: &mut WebServer,
) -> Result<()> {
// Make sure to save artifacts regardless of if we're opening the app or not
@@ -555,7 +587,8 @@ impl AppServer {
let displayed_address = devserver.displayed_address();
// Always open the server first after the client has been built
if let Some(server) = self.server.as_mut() {
// Only open the server if it isn't prerendered
if let Some(server) = self.server.as_mut().filter(|_| !self.ssg) {
tracing::debug!("Opening server build");
server.soft_kill().await;
server