diff --git a/adrs/0001-frontend-runtime-env-var-injection.md b/adrs/0001-frontend-runtime-env-var-injection.md new file mode 100644 index 0000000000..2ca8c0409c --- /dev/null +++ b/adrs/0001-frontend-runtime-env-var-injection.md @@ -0,0 +1,67 @@ +# Injection au runtime des variable d'env dans le frontend + +Date: 22/11/2023 + +## Statut + +Résolu + +## Contexte + +Lors du passage de `CRA` à `Vite`, on a perdu la possibilité d'injecter des variables d'environnements au frontend au runtime. + +Pour respecter les 12-factor app et avoir plus d'agilité dans la gestion des variables d'env, nous allons rajouter cette feature. + +Trois options : +1. Utiliser `import-meta-env` qui injecte dans l'`ENTRYPOINT` docker du backend les variables +2. Ajouter un controlleur `Index` dans le backend, qui retourne le contenu de `index.html` lans lequel il injecte des balises `meta` qui contiennent les variables +3. Utiliser le script `env.sh`, qui injecte dans l'`ENTRYPOINT` docker du backend les variables dans le frontend avec le CLI `sed` + +### Utiliser `import-meta-env` + +Cette méthode utilise un fichier `.env.template` qui défini les variables à injecter dynamiquement et gére le développement `compile-time` et la production `runtime`. + +Un fichier `.env.example` permet de filtrer les variables à injecter dans le frontend. + +Il faut rajouter dans l'image docker finale le script `import-meta-env` (préalablement packagé avec `npx pkg`) pour effectuer l'injection dans le fichier `index.html`. + +Cette méthode nécessite de rajouter une nouvelle lib dans notre étape de build. + +### Ajouter un controlleur `Index` dans le backend + +Cette méthode demande: +- D'ajouter les balises `meta` dans le payload retourné sur `/`. (i.e ``) +- De rendre les nom d'assets déterministes (i.e `/assets/index.js`) + - Cela nous oblige à avoir la gestion du cache dans ce controlleur, avec par exemple un `hash=randomString` généré au démarrage +- L'objet JS généré à la volée avec les balises `meta` ne sera pas typé +- Il faut modifier l'env de dev pour avoir + - un build `Vite` "watché" au lieu d'un run de dev watché par défaut + - un `.setCacheControl()` dans le backend pour éviter le caching en dev + +### Utiliser le script `env.sh` + +Ce script utilise un object `env` pour stocker les variables (i.e): +``` +self.env = { + REACT_APP_MONITORENV_URL: '__REACT_APP_MONITORENV_URL__' +} +``` + +Et un script au démarrage de l'image docker avec `ENTRYPOINT ["/home/monitorfish/env.sh"]` (i.e): +``` +sed -i 's#__REACT_APP_MONITORENV_URL__#'"$REACT_APP_MONITORENV_URL"'#g' /home/monitorfish/public/env.js +``` + +- Cette méthode construit un objet `env` non-typé + +## Décision + +Nous rajoutons une injection au runtime des dépendances avec `import-meta-env`. + +Cet outil permet: +1) De ne pas dupliquer la spécification des variables +2) Ne change pas la façon de gérer les env var de `Vite`: `import.meta.env` + +## Conséquences + +Nos devons **obligatoirement** spécifier toutes les variables d'env dans le docker-compose lors du run de l'application `backend` (qui contient le frontend). diff --git a/frontend/.env.example b/frontend/.env.example new file mode 100644 index 0000000000..4b627b3ee3 --- /dev/null +++ b/frontend/.env.example @@ -0,0 +1,12 @@ +FRONTEND_GEOSERVER_LOCAL_URL= +FRONTEND_GEOSERVER_REMOTE_URL= +FRONTEND_IS_DEV_ENV= +FRONTEND_MAPBOX_KEY= +FRONTEND_MONITORENV_URL= +FRONTEND_OIDC_AUTHORITY= +FRONTEND_OIDC_CLIENT_ID= +FRONTEND_OIDC_ENABLED= +FRONTEND_OIDC_REDIRECT_URI= +FRONTEND_SENTRY_DSN= +FRONTEND_SHOM_KEY= +VITE_SMALL_CHAT_SNIPPET= diff --git a/frontend/cypress/docker-compose.yml b/frontend/cypress/docker-compose.yml index a43f1bff98..840d6a35f8 100644 --- a/frontend/cypress/docker-compose.yml +++ b/frontend/cypress/docker-compose.yml @@ -34,6 +34,18 @@ services: - SENTRY_DSN= - MONITORENV_URL=http://geoserver-monitorenv-stubs:8080 - MONITORFISH_API_PROTECTED_API_KEY=APIKEY + - FRONTEND_GEOSERVER_LOCAL_URL=http://0.0.0.0:8081 + - FRONTEND_GEOSERVER_REMOTE_URL=http://0.0.0.0:8081 + - FRONTEND_IS_DEV_ENV=true + - FRONTEND_MAPBOX_KEY=pk.eyJ1IjoibW9uaXRvcmZpc2giLCJhIjoiY2tsdHJ6dHhhMGZ0eDJ2bjhtZmJlOHJmZiJ9.bdi1cO-cUcZKXdkEkqAoZQ + - FRONTEND_MONITORENV_URL=http://0.0.0.0:8081 + - FRONTEND_OIDC_AUTHORITY=https://authentification.recette.din.developpement-durable.gouv.fr/authSAML/oidc/monitorfish + - FRONTEND_OIDC_CLIENT_ID=monitorfish + - FRONTEND_OIDC_ENABLED=false + - FRONTEND_OIDC_REDIRECT_URI=https://monitorfish.din.developpement-durable.gouv.fr + - FRONTEND_SENTRY_DSN=https://a5f3272efa794bb9ada2ffea90f2fec5@sentry.incubateur.net/8 + - FRONTEND_SHOM_KEY=rg8ele7cft4ujkwjspsmtwas + - VITE_SMALL_CHAT_SNIPPET= ports: - 8880:8880 - 8000:8000 diff --git a/frontend/cypress/support/e2e.ts b/frontend/cypress/support/e2e.ts index d649ea10da..870955ff8c 100644 --- a/frontend/cypress/support/e2e.ts +++ b/frontend/cypress/support/e2e.ts @@ -114,54 +114,8 @@ beforeEach(() => { statusCode: 200 }) - // DEV :: VITE_GEOSERVER_LOCAL_URL - // PROD :: VITE_GEOSERVER_LOCAL_URL - cy.intercept({ url: /^https?:\/\/10\.56\.205\.25:808(1|2)\/.*/ }, req => { - req.redirect( - req.url - .replace('http://10.56.205.25:8081', 'http://0.0.0.0:8081') - .replace('http://10.56.205.25:8082', 'http://0.0.0.0:8081') - .replace('https://10.56.205.25:8081', 'http://0.0.0.0:8081') - .replace('https://10.56.205.25:8082', 'http://0.0.0.0:8081') - ) - }) - - // DEV :: VITE_GEOSERVER_REMOTE_URL - cy.intercept({ url: /^https?:\/\/monitorfish-test\.csam\.e2\.rie\.gouv\.fr\/.*/ }, req => { - req.redirect( - req.url - .replace('http://monitorfish-test.csam.e2.rie.gouv.fr', 'http://0.0.0.0:8081') - .replace('https://monitorfish-test.csam.e2.rie.gouv.fr', 'http://0.0.0.0:8081') - ) - }) - // PROD :: VITE_GEOSERVER_REMOTE_URL - cy.intercept({ url: /^https?:\/\/monitorfish\.din\.developpement-durable\.gouv\.fr\/.*/ }, req => { - req.redirect( - req.url - .replace('http://monitorfish.din.developpement-durable.gouv.fr', 'http://0.0.0.0:8081') - .replace('https://monitorfish.din.developpement-durable.gouv.fr', 'http://0.0.0.0:8081') - ) - }) - - // DEV :: VITE_MONITORENV_URL - cy.intercept({ url: /^https?:\/\/monitorenv\.kadata\.fr\/.*/ }, req => { - req.redirect( - req.url - .replace('http://monitorenv.kadata.fr', 'http://0.0.0.0:8081') - .replace('http://monitorenv.kadata.fr', 'https://0.0.0.0:8081') - ) - }) - // PROD :: VITE_MONITORENV_URL - cy.intercept({ url: /^https?:\/\/monitorenv\.din\.developpement-durable\.gouv\.fr\/.*/ }, req => { - req.redirect( - req.url - .replace('http://monitorenv.din.developpement-durable.gouv.fr', 'http://0.0.0.0:8081') - .replace('https://monitorenv.din.developpement-durable.gouv.fr', 'http://0.0.0.0:8081') - ) - }) - - // DEV :: VITE_SENTRY_DSN - // PROD :: VITE_SENTRY_DSN + // DEV :: FRONTEND_SENTRY_DSN + // PROD :: FRONTEND_SENTRY_DSN cy.intercept( { url: /^https:\/\/a5f3272efa794bb9ada2ffea90f2fec5@sentry\.incubateur\.net\/.*/ }, { @@ -169,7 +123,7 @@ beforeEach(() => { } ) - // PROD :: VITE_SMALL_CHAT_SNIPPET + // PROD :: FRONTEND_SMALL_CHAT_SNIPPET cy.intercept( { url: /^https:\/\/embed\.small\.chat\/.*/ }, { diff --git a/frontend/index.html b/frontend/index.html index 46002f0cf9..ad93b5a08e 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -13,7 +13,16 @@
+ + %VITE_SMALL_CHAT_SNIPPET% + + + + +