From 37be55242deadc80353ebe4649a4883c1e1fd441 Mon Sep 17 00:00:00 2001 From: Dave Date: Mon, 16 Feb 2026 17:05:09 +0000 Subject: [PATCH] Auto-build the fronted into the release binary on cargo build --release --- README.md | 18 ++++++++---------- server/build.rs | 50 +++++++++++++++++++++++++++++++------------------ 2 files changed, 40 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 810c2ac..8199a3c 100644 --- a/README.md +++ b/README.md @@ -3,30 +3,28 @@ This app runs as a single Rust web server binary that serves the Vite/React frontend and exposes APIs. The frontend lives in the `frontend/` directory. +You can also run the frontend and backend separately in development (Vite dev server + Rust API). + ## Running it in development ```bash # Build the frontend cd frontend -pnpm install -pnpm build -cd .. +pnpm install +pnpm dev # Run the server (serves embedded frontend/dist/) cargo run ``` -## Running it in production +## Production ```bash -# Build the frontend -cd frontend -pnpm install -pnpm build -cd .. +# Build the release binary (also builds the frontend via build.rs) +cargo build --release # Run the server (serves embedded frontend/dist/) -cargo run +./target/release/story-kit-server ``` diff --git a/server/build.rs b/server/build.rs index 4e396fc..50f5e24 100644 --- a/server/build.rs +++ b/server/build.rs @@ -1,23 +1,37 @@ -use std::fs; +use std::env; use std::path::Path; +use std::process::Command; -fn main() { - let dist_dir = Path::new("../frontend/dist"); +fn run(cmd: &str, args: &[&str], dir: &Path) { + let status = Command::new(cmd) + .args(args) + .current_dir(dir) + .status() + .unwrap_or_else(|e| panic!("Failed to run {} {:?}: {}", cmd, args, e)); - println!("cargo:rerun-if-changed=build.rs"); - - if let Ok(entries) = fs::read_dir(dist_dir) { - for entry in entries.flatten() { - let path = entry.path(); - if path.is_dir() { - if let Ok(sub_entries) = fs::read_dir(&path) { - for sub_entry in sub_entries.flatten() { - println!("cargo:rerun-if-changed={}", sub_entry.path().display()); - } - } - } else { - println!("cargo:rerun-if-changed={}", path.display()); - } - } + if !status.success() { + panic!("Command failed: {} {:?}", cmd, args); } } + +fn main() { + println!("cargo:rerun-if-changed=build.rs"); + println!("cargo:rerun-if-env-changed=PROFILE"); + println!("cargo:rerun-if-changed=../frontend/package.json"); + println!("cargo:rerun-if-changed=../frontend/pnpm-lock.yaml"); + println!("cargo:rerun-if-changed=../frontend/vite.config.ts"); + println!("cargo:rerun-if-changed=../frontend/index.html"); + println!("cargo:rerun-if-changed=../frontend/src"); + println!("cargo:rerun-if-changed=../frontend/public"); + + let profile = env::var("PROFILE").unwrap_or_default(); + if profile != "release" { + return; + } + + let frontend_dir = Path::new("../frontend"); + + // Ensure dependencies are installed and build the frontend bundle. + run("pnpm", &["install"], frontend_dir); + run("pnpm", &["build"], frontend_dir); +}