- Introduce cache busting (to circumvent aggressive caching on iOS - but ideal in other contexts as well)

- Change the build process to allow cache busting
- Optimisations to the build process
- Several improvements of UI geared towards mobile experience
-
This commit is contained in:
Josako
2025-09-25 17:28:01 +02:00
parent cc47ce2d32
commit 16ce59ae98
32 changed files with 1538 additions and 899 deletions

View File

@@ -0,0 +1,106 @@
# Cache busting, builds en distributie (Parcel v2 + manifest)
Dit document beschrijft hoe cache busting nu structureel is geïmplementeerd met Parcel v2 (filename hashing) en hoe je builds en distributie uitvoert in de verschillende omgevingen.
## Overzicht van de aanpak
- Parcel v2 bouwt de frontend bundles met content-hashes in de bestandsnamen (bijv. `/static/dist/chat-client.abcd123.js`).
- We bouwen via minimale HTML entries (frontend_src/entries/*.html) die de JS importeren; dit dwingt Parcel tot consistente hashing en CSS-extractie.
- Na de build schrijven we een `manifest.json` in `nginx/static/dist/` met een mapping van logische namen naar gehashte paden.
- Templates gebruiken nu `asset_url('dist/chat-client.js|css')` om automatisch naar de juiste gehashte bestanden te verwijzen.
- Nginx (DEV/TEST) is ingesteld om voor `/static/dist/` lange cache headers te sturen: `Cache-Control: public, max-age=31536000, immutable`.
- HTML krijgt geen agressieve caching via Nginx; de browser ontdekt bij volgende request de nieuwe gehashte asset-URLs.
- In STAGING/PROD (Ingress + Bunny) volg je dezelfde principes; CDN ziet unieke URLs en cachet langdurig, zonder purges te vereisen.
## Relevante bestanden die zijn aangepast/toegevoegd
- `nginx/package.json`
- DevDependency: `@parcel/reporter-bundle-manifest` toegevoegd.
- `postbuild` script toegevoegd (optioneel; puur informatief).
- `nginx/.parcelrc`
- Parcel reporter geconfigureerd zodat `manifest.json` wordt weggeschreven.
- `common/utils/template_filters.py`
- Nieuwe Jinja global `asset_url(logical_path)` geregistreerd.
- `eveai_chat_client/asset_manifest.py`
- Hulpfuncties om manifest in te lezen en paden te resolven met caching.
- `eveai_chat_client/templates/base.html` en `templates/scripts.html`
- CSS/JS referenties omgezet naar `{{ asset_url('dist/chat-client.css|js') }}`.
- `nginx/nginx.conf`
- Extra location voor `/static/dist/` met lange cache headers.
## Build uitvoeren (lokaal of in CI)
1. Ga naar de `nginx` directory.
2. Installeer dependencies (eenmalig of na wijzigingen):
- `npm install`
3. Run build:
- `npm run clean`
- `npm run build`
Resultaat:
- Bundles met content-hash in `nginx/static/dist/`
- `nginx/static/dist/manifest.json` aanwezig
Tip: De build wordt ook aangeroepen door het bestaande script `docker/rebuild_chat_client.sh`.
## rebuild_chat_client.sh
Script: `docker/rebuild_chat_client.sh`
- Kopieert client images naar `nginx/static/assets/img`.
- Voert vervolgens `npm run clean` en `npm run build` uit in `nginx/`.
- Bouwt en pusht daarna de `nginx` container.
Door de nieuwe Parcel configuratie zal de build automatisch `manifest.json` genereren en gehashte assets outputten. Er zijn geen extra stappen nodig in dit script.
## Hoe de templates de juiste bestanden vinden
- De Jinja global `asset_url()` zoekt in `manifest.json` de gehashte bestandsnaam op basis van een logische naam.
- Voorbeelden in templates:
- CSS: `{{ asset_url('dist/chat-client.css') }}`
- JS: `{{ asset_url('dist/chat-client.js') }}`
- Als het manifest onverhoopt ontbreekt (bijv. in een edge-case), valt `asset_url` automatisch terug naar het on-gehashte pad onder `/static/` zodat de pagina niet breekt.
## Nginx (DEV/TEST)
In `nginx/nginx.conf` is toegevoegd:
```
location ^~ /static/dist/ {
alias /etc/nginx/static/dist/;
add_header Cache-Control "public, max-age=31536000, immutable" always;
}
```
- Hiermee krijgen gehashte assets lange caching. Omdat de URL wijzigt bij iedere inhoudswijziging, halen browsers/CDN de nieuwe versie zonder problemen op.
- HTML wordt niet agressief gecachet door Nginx; wil je volledig no-cache afdwingen voor HTML, dan kun je dat ook applicatiezijde doen (Flask) of via extra Nginx rules voor specifieke HTML routes.
## Ingress (STAGING/PROD) en Bunny.net
- Ingress: Zet (indien nog niet aanwezig) voor het pad dat `/static/dist/` serveert een configuration snippet met dezelfde header:
- `add_header Cache-Control "public, max-age=31536000, immutable" always;`
- HTML/endpoints laat je kort/no-cache of standaard; belangrijk is dat templates met nieuwe gehashte URLs snel door de clients worden opgepakt.
- Bunny.net (pull zone): CDN cachet op basis van volledige URL. Door de content-hash in de bestandsnaam zijn purges normaliter niet nodig.
## Troubleshooting / Tips
- Controleer na build of `manifest.json` bestaat:
- `ls nginx/static/dist/manifest.json`
- Inspecteer headers in DEV:
- `curl -I http://<host>/static/dist/chat-client.<hash>.js`
- Moet `Cache-Control: public, max-age=31536000, immutable` tonen.
- Als een client toch oude CSS/JS toont:
- Check of de geleverde HTML naar de nieuwste gehashte bestandsnaam verwijst (View Source / Network tab).
- Zorg dat de HTML niet op CDN langdurig wordt gecachet.
## Samenvatting workflow per omgeving
- DEV/TEST (Nginx):
1) `docker/rebuild_chat_client.sh` draaien (of handmatig `npm run build` in `nginx/`).
2) Nginx container wordt vernieuwd met nieuwe `static/dist` inclusief manifest en gehashte bundles.
- STAGING/PROD (Ingress + Bunny):
1) Zelfde build, gehashte bundles en manifest worden gedeployed via container image.
2) Ingress dient `/static/dist/` met lange cache headers.
3) Bunny.net cachet de nieuwe URLs automatisch; purgen niet nodig.
Met deze setup combineren we maximale performance (lange caching) met directe updates (nieuwe URL bij wijziging).