El manifiesto de aplicación de 12 factores hizo una contribución significativa al desarrollo y operación de aplicaciones web, pero esto afectó principalmente a los backends y pasó por alto los front-end. La mayoría de las cláusulas del manifiesto no son aplicables a las interfaces o se realizan por sí mismas, pero con el número 3 ( configuración ) hay preguntas.
El manifiesto original decía: "Mantenga la configuración en tiempo de ejecución". En la práctica, esto significa que la configuración no se puede almacenar dentro del código fuente o el artefacto final. Debe pasar a la aplicación en el momento del inicio. Esta regla tiene aplicaciones prácticas, aquí hay un par:
Una aplicación en diferentes entornos debe acceder a diferentes backends. De producción a API de producción, de prueba a prueba de API y al ejecutar pruebas de integración a un servidor simulado especial.
Para las pruebas e2e, es necesario reducir el tiempo de espera para la reacción del usuario. Por ejemplo, si algo sucede en el sitio después de 10 minutos de inactividad, entonces para un escenario de prueba puede reducir este intervalo a un minuto.
SSR
Si la aplicación de front-end contiene SSR, la tarea se vuelve un poco más sencilla. La configuración se pasa como variables de entorno a la aplicación en el servidor; cuando se procesa, entra en la respuesta al cliente como variables globales declaradas al <script>
principio de la página. En el cliente, es suficiente recoger estas variables del alcance global y usarlas.
Recientemente, en Aviasales, creamos una aplicación para renderizar partes del sitio en el servidor y nos enfrentamos a este problema. El resultado es mi compañero de equipo zaopensorsil - isomorphic -env-webpack-plugin .
El hermoso Next.js hace esto de inmediato , no es necesario que haga nada especial.
RSE
, — . , , . , .
:
–
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.
Hay un caso de borde más pequeño en este esquema: generalmente se agrega un hash de contenido a los nombres de los archivos con recursos, de modo que en el navegador todos los archivos se pueden almacenar en caché para siempre por nombre sin ningún problema. En este caso, debe complicar un poco el script para generar un archivo con variables, aplicar un hash al contenido y agregar el resultado al nombre del archivo.
Conclusión
El trabajo correcto con los parámetros de la aplicación front-end ayuda a crear sistemas confiables y fáciles de usar. Basta con desacoplar la configuración de la aplicación y pasarla al tiempo de ejecución para mejorar radicalmente la comodidad de los miembros del equipo y reducir los posibles errores.
¿Cómo se pasan las configuraciones a las aplicaciones cliente?