Bagian depan yang solid: konfigurasi

Manifesto aplikasi 12 faktor memberikan kontribusi yang signifikan untuk pengembangan dan pengoperasian aplikasi web, tetapi ini sebagian besar memengaruhi backend, dan melewati front-end. Sebagian besar klausa dalam manifes tidak berlaku untuk frontend, atau dilakukan sendiri, tetapi dengan nomor 3 - konfigurasi - ada pertanyaan.





Manifes asli mengatakan, "Pertahankan konfigurasi saat runtime". Dalam praktiknya, ini berarti bahwa konfigurasi tidak dapat disimpan di dalam kode sumber atau artefak terakhir. Itu harus diteruskan ke aplikasi pada waktu startup. Aturan ini memiliki penerapan praktis, berikut ini beberapa:





  1. Aplikasi di lingkungan yang berbeda harus mengakses backend yang berbeda. Tentang produksi - ke API produksi, tentang penahapan - ke penahapan API, dan saat menjalankan pengujian integrasi - ke server tiruan khusus.





  2. Untuk pengujian e2e, perlu untuk mengurangi waktu tunggu reaksi pengguna. Misalnya, jika sesuatu terjadi di situs setelah 10 menit tidak ada aktivitas, maka untuk skenario pengujian Anda dapat mengurangi interval ini menjadi satu menit.





SSR

Jika aplikasi front-end berisi SSR, tugasnya menjadi sedikit lebih mudah. Konfigurasi tersebut diteruskan sebagai variabel lingkungan ke aplikasi di server; saat dirender, konfigurasi tersebut masuk ke respons ke klien sebagai variabel global yang dideklarasikan di <script>



bagian paling awal halaman. Pada klien, cukup mengambil variabel ini dari cakupan global dan menggunakannya.





Baru-baru ini, di Aviasales, kami membuat aplikasi untuk server rendering bagian situs dan dihadapkan pada masalah ini. Hasilnya adalah rekan setim saya zaopensorsil - isomorphic-env-webpack-plugin .





Next.js yang cantik melakukan ini di luar kotak , Anda tidak perlu melakukan sesuatu yang khusus.





CSR

, — . , , . , .





:





  1. config.js



    , . , . — -, -, — -. — PR .





  2. . DefinePlugin



    Webpack. — . — , . , , . .





.





-

- :





  1. nginx, nginx -. nginx .





  2. , — 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 .





, , .





.





. Caddy , Traefik .





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.





Ada satu kasus tepi kecil lagi dalam skema ini - biasanya hash konten ditambahkan ke nama file dengan sumber daya, sehingga di browser semua file dapat di-cache selamanya dengan nama tanpa masalah. Dalam kasus ini, Anda perlu sedikit memperumit skrip untuk membuat file dengan variabel, mencirikan konten, dan menambahkan hasilnya ke nama file.





Kesimpulan

Pekerjaan yang benar dengan parameter aplikasi front-end membantu menciptakan sistem yang andal dan mudah digunakan. Cukup memisahkan konfigurasi dari aplikasi dan memindahkannya ke runtime untuk secara radikal meningkatkan kenyamanan anggota tim dan mengurangi potensi kesalahan.





Bagaimana Anda meneruskan konfigurasi ke aplikasi klien?








All Articles