Note: This site is currently "Under construction". I'm migrating to a new version of my site building software. Lots of things are in a state of disrepair as a result (for example, footnote links aren't working). It's all part of the process of building in public. Most things should still be readable though.

Watch Multiple Folders And Reload A Web Page Served By axum When Something Changes

This is how I'm watching multiple directoires to trigger a live reload of a web page that's loaded from an axum server

Code

#!/usr/bin/env cargo +nightly -Zscript

//! ```cargo
//! [dependencies]
//! axum = "0.7.4"
//! tokio = { version = "1.35.1", features = ["rt-multi-thread", "macros"] }
//! tower-http = { version = "0.5.1", features = ["fs"] }
//! tower-livereload = "0.9.1"
//! notify = "6.1.1"
//! notify-debouncer-mini = "0.4.1"
//! ```

use tower_livereload::LiveReloadLayer;
use axum::Router;
use tower_http::services::ServeDir;
use std::path::PathBuf;
use std::path::Path;
use notify_debouncer_mini::{new_debouncer, notify::*, DebounceEventResult};
use std::time::Duration;

#[tokio::main]
async fn main() {
  run_web_server().await;
}

async fn run_web_server() {
    let livereload = LiveReloadLayer::new();
    let reloader1 = livereload.reloader();
    let reloader2 = livereload.reloader();
    let app = Router::new()
    .nest_service(
        "/",
        ServeDir::new(PathBuf::from("site_folder")),
    )
    .layer(livereload);

    let mut debouncer1 = new_debouncer(
        Duration::from_millis(150),
        move |res: DebounceEventResult| match res {
            Ok(_events) => reloader1.reload(),
            Err(e) => println!("Error {:?}", e),
        },
    )
    .unwrap();

    debouncer1
      .watcher()
      .watch(
          Path::new("files_folder_1"),
          RecursiveMode::Recursive,
      )
      .unwrap();

    let mut debouncer2 = new_debouncer(
        Duration::from_millis(150),
        move |res: DebounceEventResult| match res {
            Ok(_events) => reloader2.reload(),
            Err(e) => println!("Error {:?}", e),
        },
    )
    .unwrap();

    debouncer2
      .watcher()
      .watch(
          Path::new("files_folder_2"),
          RecursiveMode::Recursive,
      )
      .unwrap();

    if let Ok(listener) = tokio::net::TcpListener::bind("localhost:4343").await {
        if (axum::serve(listener, app).await).is_ok() {
            // Server is going at this point
        }
    }

}