# 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 applicatie‑zijde 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:///static/dist/chat-client..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).