Configurer le re-build automatique de l'app front lors de changements #47

Merged
kosssi merged 7 commits from html_auto_reload into main 2024-08-09 15:50:54 +02:00
5 changed files with 49 additions and 5 deletions
Showing only changes of commit 1ae80c161f - Show all commits

5
.ignore Normal file
View File

@ -0,0 +1,5 @@
# Ignorer les fichiers dont ne dépent pas la compilation
*.md
tailwind.config.js
*.example
scripts

12
Cargo.lock generated
View File

@ -69,6 +69,7 @@ dependencies = [
"askama",
"askama_axum",
"axum",
"listenfd",
"serde",
"tokio",
"tower-http",
@ -1717,6 +1718,17 @@ dependencies = [
"libc",
]
[[package]]
name = "listenfd"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0500463acd96259d219abb05dc57e5a076ef04b2db9a2112846929b5f174c96"
dependencies = [
"libc",
"uuid",
"winapi",
]
[[package]]
name = "lock_api"
version = "0.4.12"

View File

@ -7,7 +7,7 @@ edition = "2021"
askama = "0.12.1"
askama_axum = "0.4.0"
axum = "0.7.5"
listenfd = "1.0.1"
serde = { version = "1.0.204", features = ["derive"] }
tokio = { version = "1.39.1", features = ["macros", "rt-multi-thread"] }
tower-http = { version = "0.5.2", features = ["fs"] }

View File

@ -13,3 +13,17 @@
```bash
cargo run --bin app
```
## L'auto-reload
Pour permettre au projet de s'auto-recharger lors du développement, nous avons besoin de 2 librairies :
```bash
cargo install cargo-watch systemfd
```
Pour recompiler automatiquement le serveur lors de changement :
```bash
systemfd --no-pid -s http::3000 -- cargo watch -x 'run --bin app'
```

View File

@ -1,6 +1,8 @@
use ::app::get_router;
use listenfd::ListenFd;
use std::env;
use std::path::Path;
use tokio::net::TcpListener;
#[tokio::main]
async fn main() {
@ -8,10 +10,21 @@ async fn main() {
let assets_path = Path::new(&manifest_dir).join("assets");
kosssi marked this conversation as resolved Outdated

Ça vaudrait le coup de "comprendre" pourquoi on exclue les requêtes htmx dans ce contexte, et de l'expliquer en docstring de la fonction

(PS : les docstrings se font avec ### bla bla bla au dessus de la fonction)

Ça vaudrait le coup de "comprendre" pourquoi on exclue les requêtes htmx dans ce contexte, et de l'expliquer en docstring de la fonction (PS : les docstrings se font avec `### bla bla bla` au dessus de la fonction)

Le pourquoi du comment vient de cette issue dont le fix a été cette PR

En gros, c'est pour éviter que le script JS qui se gère du livereload côté client ne soit injecté dans chaque requête htmx ; car on n'en a besoin que sur la requête qui charge la page de "base".

Ça devrait donc, en effet, être approprié pour nous d'avoir ce mécanisme

PS : astuce, pour trouver cette info, j'ai cherché la ligne de code en question dans les PR github ;)

Le pourquoi du comment vient de cette [issue](https://github.com/leotaku/tower-livereload/issues/2) dont le fix a été cette [PR](https://github.com/leotaku/tower-livereload/pull/3) En gros, c'est pour éviter que le script JS qui se gère du livereload côté client ne soit injecté dans chaque requête htmx ; car on n'en a besoin que sur la requête qui charge la page de "base". Ça devrait donc, en effet, être approprié pour nous d'avoir ce mécanisme PS : astuce, pour trouver cette info, j'ai [cherché](https://github.com/search?q=%21req.headers%28%29.contains_key%28%22hx-request%22%29&type=pullrequests) la ligne de code en question dans les PR github ;)

J'ai ajouté de la documentation :

Nous filtrons les requêtes de htmx pour ne pas inclure le script JS qui gère le rechargement (Référence).

J'ai ajouté de la documentation : > Nous filtrons les requêtes de `htmx` pour ne pas inclure le script _JS_ qui gère le rechargement ([Référence](https://github.com/leotaku/tower-livereload/pull/3)).
let router = get_router(assets_path.as_path());
// TODO: select port based on available port (or ask in CLI)
let listener = tokio::net::TcpListener::bind("localhost:3000")
let mut listenfd = ListenFd::from_env();
let listener = match listenfd.take_tcp_listener(0).unwrap() {
// if we are given a tcp listener on listen fd 0, we use that one
Some(listener) => {
listener.set_nonblocking(true).unwrap();
TcpListener::from_std(listener).unwrap()
}
// otherwise fall back to local listening
None => TcpListener::bind("localhost:3000").await.unwrap(),
};
kosssi marked this conversation as resolved Outdated

Ça vaut le coup de passer à la ligne, quand y'a de la programmation "fonctionnelle" comme ça, à base de layers qui s'empilent :

let router = get_router(assets_path.as_path())
    .layer(livereload.request_predicate(not_htmx_predicate));
Ça vaut le coup de passer à la ligne, quand y'a de la programmation "fonctionnelle" comme ça, à base de layers qui s'empilent : ``` let router = get_router(assets_path.as_path()) .layer(livereload.request_predicate(not_htmx_predicate)); ```

Du coup je laisse pour l'instant fmt formater comme il veut ;)

Du coup je laisse pour l'instant `fmt` formater comme il veut ;)
println!("Listening on: http://{}", listener.local_addr().unwrap());
// Run the server with the router
kosssi marked this conversation as resolved Outdated

Je pense qu'il faut également watch le dossier assets/ pour reload quand il y a des changements dans les fichiers ".js", ".css", etc.

cf https://github.com/leotaku/tower-livereload/blob/master/examples/axum-htmx/src/main.rs

Je pense qu'il faut également `watch` le dossier `assets/` pour reload quand il y a des changements dans les fichiers ".js", ".css", etc. cf https://github.com/leotaku/tower-livereload/blob/master/examples/axum-htmx/src/main.rs

Actuellement lorsque je modifie un fichier CSS ça recharge la page. Je ne comprends pas vraiment pourquoi mais c'est bien le cas.

Actuellement lorsque je modifie un fichier _CSS_ ça recharge la page. Je ne comprends pas vraiment pourquoi mais c'est bien le cas.
axum::serve(listener, router.into_make_service())
.await
.unwrap();
println!("Listening on: http://{}", listener.local_addr().unwrap());
axum::serve(listener, router).await.unwrap();
}