Das 12-Faktor-Anwendungsmanifest leistete einen wesentlichen Beitrag zur Entwicklung und zum Betrieb von Webanwendungen. Dies betraf jedoch hauptsächlich Backends und umging die Frontends. Die meisten Klauseln im Manifest gelten entweder nicht für Frontends oder sie werden von sich aus ausgeführt, aber bei Nummer 3 - Konfiguration - gibt es Fragen.
Das ursprüngliche Manifest lautete: "Behalten Sie die Konfiguration zur Laufzeit bei." In der Praxis bedeutet dies, dass die Konfiguration nicht im Quellcode oder im endgültigen Artefakt gespeichert werden kann. Es muss beim Start an die Anwendung übergeben werden. Diese Regel hat praktische Anwendungen, hier einige:
Eine Anwendung in verschiedenen Umgebungen muss auf verschiedene Backends zugreifen. Bei der Produktion - zur Produktions-API, zum Staging - zum API-Staging und beim Ausführen von Integrationstests - zu einem speziellen Mock-Server.
Für e2e-Tests muss die Wartezeit für die Reaktion des Benutzers verkürzt werden. Wenn beispielsweise nach 10 Minuten Inaktivität etwas auf der Site passiert, können Sie dieses Intervall für ein Testszenario auf eine Minute reduzieren.
SSR
Wenn die Front-End-Anwendung SSR enthält, wird die Aufgabe etwas einfacher. Die Konfiguration wird als Umgebungsvariable an die Anwendung auf dem Server übergeben. Beim Rendern wird sie als globale Variablen, <script>
die ganz am Anfang der Seite deklariert werden, an den Client gesendet . Auf dem Client reicht es aus, diese Variablen aus dem globalen Bereich zu übernehmen und zu verwenden.
Vor kurzem haben wir bei Aviasales eine Anwendung für das Server-Rendering von Teilen der Site erstellt und waren mit diesem Problem konfrontiert. Das Ergebnis ist mein Teamkollege zaopensorsil - isomorphic-env-webpack-plugin .
Die schöne Next.js erledigt dies sofort , Sie müssen nichts Besonderes tun.
CSR
, — . , , . , .
:
–
config.js
, . , . — -, -, — -. — PR .
.
DefinePlugin
Webpack. — . — , . , , . .
.
-
- :
nginx, nginx -. nginx .
, — API.
— , nginx . /user-api/path
https://user.my-service.io/path
, /auth-api/path
https://auth.other-service.io/path
.
nginx Docker-
1.19 Docker- nginx . .template
/etc/nginx/templates
. , .
nginx SPA :
server {
listen 8080;
root /srv/www;
index index.html;
server_name _;
location /user-api {
proxy_pass ${USER_API_URL};
}
location /auth-api {
proxy_pass ${AUTH_API_URL};
}
location / {
try_files $uri /index.html;
}
}
Dockerfile :
FROM node:14.15.0-alpine as build
WORKDIR /app
#
# ...
FROM nginx:1.19-alpine
COPY ./default.conf.template /etc/nginx/templates/default.conf.template
COPY --from=build /app/public /srv/www
EXPOSE 8080
, nginx .
, , .
API, - .
-, . , .
JS-:
window.__ENV__ = {
USER_API_URL: 'https://user.my-service.io/',
AUTH_API_URL: 'https://auth.other-service.io/',
};
, . . <script>
HTML- .
nginx Docker-
, , — API, . , , env.dict
:
BACK_URL
GOOGLE_CLIENT_ID
Bash- generate_env.sh
JS-:
#!/bin/bash
filename='/etc/nginx/env.dict'
# JS-
config_str="window._env_ = { "
# JS-
while read line; do
variable_str="${line}: \"${!line}\""
config_str="${config_str}${variable_str}, "
done < $filename
# JS-
config_str="${config_str} };"
#
echo "Creating config-file with content: \"${config_str}\""
echo "${config_str}" >> /srv/www/config.env.js
# <script> HTML-
sed -i '/<\/body><\/html>/ i <script src="/confit.env.js"></script>' *.html
Bash, . , .
nginx , nginx. cmd.sh
, :
#!/bin/bash
bash /etc/nginx/generate_env.sh
nginx -g "daemon off;"
Dockerfile:
FROM node:14.15.0-alpine as build
WORKDIR /app
#
# ...
FROM nginx:1.19-alpine
# Alpine Bash,
RUN apk add bash
COPY ./default.conf /etc/nginx/conf.d/
COPY --from=build /app/public /srv/www
COPY ./cmd.sh /etc/nginx/cmd.sh
COPY ./generate_env.sh /etc/nginx/generate_env.sh
COPY ./env.dict /etc/nginx/env.dict
EXPOSE 8080
CMD ["bash", "/etc/nginx/cmd.sh"]
— env.dict
.
, , SSR . isomorphic-env-webpack-plugin, : HTML.
In diesem Schema gibt es noch einen kleinen Randfall: Normalerweise wird den Namen von Dateien mit Ressourcen ein Inhalts-Hash hinzugefügt, sodass im Browser alle Dateien ohne Probleme für immer nach Namen zwischengespeichert werden können. In diesem Fall müssen Sie das Skript zum Generieren einer Datei mit Variablen etwas komplizieren, den Inhalt hashen und das Ergebnis dem Dateinamen hinzufügen.
Fazit
Durch korrektes Arbeiten mit den Parametern der Front-End-Anwendung können zuverlässige und benutzerfreundliche Systeme erstellt werden. Es reicht aus, die Konfiguration von der Anwendung zu entkoppeln und zur Laufzeit zu verschieben, um den Komfort der Teammitglieder radikal zu verbessern und mögliche Fehler zu reduzieren.
Wie übergeben Sie Konfigurationen an Clientanwendungen?