use mini_static::{CssOptions, CssTool, JsOptions, JsTool, Server};
use std::env;
use std::path::Path;
use std::time::Duration;
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let port = env::var("PORT")
.unwrap_or_else(|_| "8080".to_string())
.parse::<u16>()?;
let root = env::var("ROOT").unwrap_or_else(|_| "./public".to_string());
let root_path = Path::new(&root);
let server = Server::new(root_path)?.with_immutable_assets(|path| {
path.file_name()
.and_then(|name| name.to_str())
.is_some_and(|name| name.contains(".a1b2c3."))
});
let css_src = Path::new("./css-src");
let js_src = Path::new("./js-src");
let mut server = server;
let has_css_bundle = if css_src.exists() {
match server.clone().with_source_folder(css_src) {
Ok(s) => {
server = s.with_css_tool(
CssTool::LightningCss,
CssOptions::new()
.bundle(true)
.minify(true)
.bundle_output_name("style-bundle.css"),
);
true
}
Err(e) => {
eprintln!("warning: CSS bundling configuration failed: {}", e);
false
}
}
} else {
false
};
let has_js_bundle = if js_src.join("main.js").exists() {
match server.clone().with_source_folder(js_src) {
Ok(s) => match s.with_js_tool(
JsTool::Esbuild,
JsOptions::new()
.bundle_entry(&js_src.join("main.js"), "bundle.js")
.minify(true),
) {
Ok(s) => {
server = s;
true
}
Err(e) => {
eprintln!("warning: JS bundling configuration failed: {}", e);
false
}
},
Err(e) => {
eprintln!("warning: JS bundling configuration failed: {}", e);
false
}
}
} else {
false
};
#[cfg(debug_assertions)]
{
server = server.with_live_reload();
}
let (_port, handle) = server.run_all(port, Duration::from_secs(30)).await?;
println!("mini-static listening on 0.0.0.0:{}", port);
println!("serving files from: {}", root);
println!("immutable caching enabled for *.a1b2c3.* (see vendor.a1b2c3.js)");
println!("precompressed sidecar demo: bundle.js / bundle.js.gz");
if has_css_bundle {
println!(
"css bundling enabled (lightningcss): {} -> {}",
css_src.display(),
root_path.join("style-bundle.css").display()
);
}
if has_js_bundle {
println!(
"js bundling enabled (esbuild): {} -> {}",
js_src.join("main.js").display(),
root_path.join("bundle.js").display()
);
}
#[cfg(debug_assertions)]
println!("live-reload enabled at {}", mini_static::LIVE_RELOAD_PATH);
tokio::signal::ctrl_c().await?;
println!("shutting down...");
handle.shutdown().await;
Ok(())
}