Run An Axum Web Server With Live Reload From Tauri
This is how I'm embedding Axum server with hot reload in a Tauri app:
[package]
name = "tauri_with_axum"
version = "0.0.1"
description = "Tauri With Axum Embedded"
license = ""
repository = ""
edition = "2021"
[build-dependencies]
tauri-build = { version = "1.5", features = [] }
[dependencies]
tauri = { version = "1.5", features = ["shell-open"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
axum = "0.7.4"
tower-http = { version = "0.5.1", features = ["fs"] }
tower-livereload = "0.9.1"
tokio = { version = "1.35.1"}
notify = "6.1.1"
notify-debouncer-mini = "0.4.1"
[features]
# this feature is used for production builds or when ``devPath`` points to the filesystem
# DO NOT REMOVE!!
custom-protocol = ["tauri/custom-protocol"]
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
use axum::Router;
use notify::Watcher;
use std::path::Path;
use tower_http::services::ServeDir;
use tower_livereload::LiveReloadLayer;
fn main() -> Result<(), Box<dyn std::error::Error>> {
tauri::Builder::default()
.setup(|_app| {
tauri::async_runtime::spawn(run_web_server());
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
Ok(())
}
async fn run_web_server() {
println!("- Starting web server");
let livereload = LiveReloadLayer::new();
let reloader = livereload.reloader();
let app = Router::new()
.nest_service(
"/",
ServeDir::new(Path::new("/Users/alan/workshop/neopoligen/_site")),
)
.layer(livereload);
if let Ok(mut watcher) = notify::recommended_watcher(move |_| reloader.reload()) {
if let Ok(_) = watcher.watch(
Path::new("/Users/alan/workshop/neopoligen/_site"),
notify::RecursiveMode::Recursive,
) {};
if let Ok(listener) = tokio::net::TcpListener::bind("localhost:3131").await {
if let Ok(_) = axum::serve(listener, app).await {
()
} else {
()
}
} else {
()
}
}
}
Notes
-
The examples for axum and tower/tower_http have a lot of
Result<(), Box<dyn std::error::Error>>
in them with?
at the end of theawait
statments. I couldn't figure out how to get that to work so I fell back toif let
- There's probaby other refinements that could be made, but this is working for me.
-- end of line --
References
-
This is what I'm using for the Neopoligen control panel
-
The web server that's embedded in Tauri with this process
-
The glue between Axum and tower_livereload
-
The middleware that doest the hot reload of the web pages when they change on disk