So gehen Sie mit umgebungsspezifischen Einstellungen in Ihren JavaScript-Apps um

Moderne Web-Apps sind… kompliziert geworden.

Heutzutage werden viele Web-Apps mit React, Angular, Vue, Ember und anderen erstellt. Diese modernen clientseitig gerenderten Apps rufen häufig Web-APIs auf, die auf separaten Servern gehostet werden. Dies führt zu einem Problem: Wie konfigurieren Sie Ihre App, um in jeder Umgebung die richtige API-URL aufzurufen?

Beispielsweise können Sie die API während der Entwicklung lokal auf localhost: 3000 hosten. In der Produktion wird die API möglicherweise auf einem anderen Server unter api.mycompany.com gehostet. Sie benötigen Ihre App, um localhost anzurufen: 3000 in Entwicklung und api.mycompany.com in Produktion. Aber wie?

Die Basis-URL ist nur ein Beispiel für Einstellungen, die sich je nach Umgebung ändern können. Sie können auch andere Einstellungen pro Umgebung für Leistungs-, Sicherheits- oder Protokollierungszwecke festlegen. Einige der folgenden Ansätze sind auch für diese allgemeinen umgebungsspezifischen Konfigurationen anwendbar. Der Einfachheit halber konzentriert sich dieser Beitrag auf Techniken zum Konfigurieren von Basis-URLs pro Umgebung.

Ich habe auf Twitter eine Umfrage mit folgenden Optionen gepostet:

Es hat sich herausgestellt, dass es viele Möglichkeiten gibt, damit umzugehen. Ich habe im Tweet-Thread viele aufschlussreiche Antworten erhalten. Ich habe unten acht Optionen zusammengefasst. Ich habe diese Optionen (lose) in der Reihenfolge bestellt, in der sie berücksichtigt werden sollen. Wenn Sie es eilig haben, sind die Optionen, die zuerst in Betracht gezogen werden müssen, ganz oben.

Option 1: Hosten Sie die API mit der App

Einfach. Hosten Sie einfach die App und die API auf demselben Webserver, sodass relative URLs überall funktionieren. Dies vermeidet sowohl das Problem mit der Basis-URL als auch Probleme mit der Herkunft.

Wann es in Betracht zu ziehen ist:

  • Ihre API wird von einer einzelnen App verwendet.
  • Sie müssen API und App nicht separat skalieren, sodass das Hosten auf demselben Server praktisch ist.

Option 2: Umgebungsspezifisches Build

Dieser Ansatz berücksichtigt die Maxime der Kompilierungszeit:

"Tun Sie niemals zur Laufzeit, was Sie zur Kompilierungszeit tun können."

Bei diesem Ansatz verwenden Sie normalerweise einen CI-Server (Continuous Integration), um benutzerdefinierte Builds für jede Umgebung zu generieren und bereitzustellen. Dies ist ein leistungsstarker, sicherer und vielseitiger Ansatz, für den jedoch jeder Entwickler eine ENV-Datei auf seinem Computer erstellen und verwalten muss. Hier ist ein großartiger Beitrag mit einigen Tricks, um dies ziemlich schmerzfrei zu machen.

Wann es in Betracht zu ziehen ist:

  • Sie können problemlos einen CI-Server konfigurieren, um den Erstellungs- und Bereitstellungsprozess zu automatisieren und die Zuverlässigkeit zu gewährleisten.
  • Sie möchten den für die Produktion bereitgestellten Code erheblich ändern, z. B. Code entfernen, der aus Leistungs- oder Sicherheitsgründen nur in Nichtproduktionsumgebungen verwendet wird.
  • Sie kennen das Risiko, das mit der Bereitstellung von anderem Code in der Produktion als dem Code verbunden ist, den Sie während der Entwicklung und der Qualitätssicherung ausgeführt haben.

Option 3: Laufzeitkonfiguration

Mit diesem Ansatz konfigurieren Sie Ihre App für jede Umgebung, indem Sie beim Start auf die relevanten Konfigurationsdaten verweisen (im Gegensatz zum oben beschriebenen Build). Im Gegensatz zum obigen Ansatz wird bei diesem Ansatz derselbe Code für alle Umgebungen bereitgestellt. Die Konfigurationsdaten, die Sie beim Start eingeben, passen das Verhalten der App an.

Es gibt verschiedene Möglichkeiten, Umgebungskonfigurationsdaten zu übergeben:

  1. Befehlszeilenkonfiguration - Übergebe die Konfiguration beim Start der App.
  2. Umgebungskonfigurationsdatei - Füllen Sie in jeder Umgebung eine ENV-Datei aus und lesen Sie sie beim Start aus. Hier ist ein Beispiel aus den Dokumenten zur Erstellung einer reaktionsfähigen Anwendung. Der Ansatz gilt jedoch für alle JavaScript-Anwendungen.

Aber wie erhält Ihre App diese Informationen? Es gibt auch ein paar Möglichkeiten, dies zu tun:

  1. Konfigurationsdatei - Schreiben Sie die Konfigurationsdaten beim Start der App in eine separate JavaScript-Datei. Ihre App kann diese Datei beim Start importieren und lesen.
  2. Global in index.html - Schreiben Sie die Konfigurationsdaten mit Ihrem Build-Tool in ein globales Verzeichnis in index.html. Hier noch einmal ein Beispiel aus den Dokumenten zur Erstellung einer reaktionsfähigen Anwendung. Der Ansatz gilt jedoch für alle JavaScript-Anwendungen.

Zugegebenermaßen ändern diese Ansätze Ihren Code beim Start geringfügig, basierend auf der bereitgestellten Laufzeitkonfiguration. Sie unterscheiden sich jedoch von der obigen Option 2, da in allen Umgebungen derselbe Code bereitgestellt wird.

Wann es in Betracht zu ziehen ist:

  • Sie bevorzugen es, denselben Code in allen Umgebungen bereitzustellen.

Option 4: Reverse Proxy

Mit diesem Ansatz rufen Sie in allen Umgebungen dieselbe relative URL auf. Wie funktioniert das? Nun, es liegt in der Verantwortung des Front-End-Webservers, Aufrufe für jede Umgebung an die entsprechende API weiterzuleiten. Dieser Ansatz bietet mehrere Vorteile:

  1. Ihre URLs in all Ihren API-Aufrufen sind saubere, relative URLs. Zum Beispiel / user.
  2. Sie können Ihren Front-End-Webserver als Cache-Ebene konfigurieren, um die Leistung zu steigern.
  3. Dieser Ansatz unterstützt das Wechseln von Back-End-Systemen durch einfaches Neukonfigurieren des Proxys.

Wann es in Betracht zu ziehen ist:

  • Sie können den Webserver in allen Umgebungen konfigurieren
  • Sie möchten eine Caching-Ebene zwischen Ihrer Benutzeroberfläche und Ihrer API implementieren.
  • Ihr Front-End-Webserver kann Anrufe zuverlässig und schnell an Ihren API-Server weiterleiten. Dieser Ansatz ist mit Performance-Kosten verbunden, da Ihr Webserver Anforderungen an einen anderen Server weiterleiten muss.

Randnotiz:

Während es sich um Proxys handelt, ist ein weiterer erwähnenswerter Proxy-Ansatz die Proxy-Middleware (dies ist ein völlig anderer Ansatz als der oben beschriebene Reverse-Proxy).

Wenn die Proxy-Middleware auf Ihrem lokalen Computer ausgeführt wird, werden Anforderungen während der Entwicklung an eine angegebene URL weitergeleitet. Wenn Sie beispielsweise ein React-Entwickler sind, verfügt die create-react-App über eine integrierte Proxy-Unterstützung. Sie verwendet die Proxy-Middleware von Webpack.

Hier erhalten Sie einen umfassenden Überblick über den Proxy-Ansatz mit React and Express.

Allerdings: Die Proxy-Middleware behebt nur das Problem mit der Basis-URL in der Entwicklung. Verwenden Sie daher eine der anderen Techniken in diesem Beitrag, um andere Umgebungen wie die Qualitätssicherung und die Produktion zu behandeln.

Option 5: Docker

Mit Docker können Sie die Benutzeroberfläche und die API als separate Container bereitstellen, jedoch ein "LAN" erstellen, in dem die Container so kommunizieren können, als ob sie sich im selben Netzwerk befinden. Auf diese Weise ändern sich die Basis-URLs nicht in jeder Umgebung. Die Container werden in allen Umgebungen identisch ausgeführt. Und Sie können relevante Umgebungsvariablen in die Container in jeder Umgebung übergeben. Schauen Sie sich Kubernetes oder Docker Swarm für diesen Ansatz an.

Wann es in Betracht zu ziehen ist:

  • Sie haben bereits in das Docker-Ökosystem investiert.

Option 6: Umgebungsschnüffeln

Bei diesem Ansatz verwenden Sie Code, um die aktuelle Umgebung zu „schnüffeln“, in der Regel durch Betrachten der URL. Wenn die URL beispielsweise http: // localhost lautet, wissen Sie, dass Sie sich in der Entwicklung befinden.

Der Vorteil dieses Ansatzes ist die Einfachheit. Entwickler müssen auf ihrem Computer nichts konfigurieren und Sie müssen auch keine Affen mit CI-Server- oder Webserverkonfigurationen verwenden.

Wann es in Betracht zu ziehen ist:

  • Sie haben eine einfache App, die eine kleine Anzahl von APIs aufruft.
  • Sie haben keinen CI-Server.
  • Ihre Unternehmenspolitik macht es schmerzhaft oder unpraktisch, die anderen oben genannten Optionen umzusetzen.
  • Sie sind nicht besorgt, wenn Personen möglicherweise die URLs zu Ihrer Nicht-Produktionsumgebung finden. (Aus Sicherheitsgründen sollte Ihre Nicht-Produktionsumgebung ohnehin nicht außerhalb Ihres Unternehmens-LAN / VPN erreichbar sein.)

Option 7: Benutzerdefinierter HTTP-Header

Konfigurieren Sie den Front-End-Webserver so, dass ein benutzerdefinierter HTTP-Header bereitgestellt wird, der die relevante Client-URL für die Umgebung enthält. Der Nachteil dieses Ansatzes ist, dass Ihre App zuerst einen HTTP-Aufruf an diese API senden muss, um die relevanten Basis-URLs für alle Umgebungen zu ermitteln.

Wann es in Betracht zu ziehen ist:

  • Ich empfehle diesen Ansatz nicht, da Ihre App einen Roundtrip-HTTP-Anruf tätigen muss, bevor sie mit dem Abrufen von Daten beginnen kann. Ich bevorzuge einen der anderen Ansätze.

Option 8: App Config-Endpunkt

Bei diesem Ansatz ruft Ihre App für alle Umgebungen dieselbe API für die App-Konfiguration unter derselben URL auf. Ihre App ruft diese API zuerst auf. Der API-Aufruf gibt die relevante Basis-URL in jeder Umgebung zurück (und möglicherweise auch andere umgebungsspezifische Einstellungen). Mit diesem Ansatz können Sie möglicherweise andere relevante umgebungsspezifische Konfigurationsdaten weitergeben.

Wann es in Betracht zu ziehen ist:

  • Ich empfehle diesen Ansatz auch nicht. Dies wirkt sich auf die Ladezeit aus, da der erste HTTP-Aufruf zum Abrufen der Konfigurationsdaten abgeschlossen sein muss, bevor die App mit dem Abrufen der gewünschten Daten beginnen kann. Betrachten Sie stattdessen eine der anderen Optionen oben.

Zusammenfassung

Erstellen Sie einen Build pro Umgebung über einen CI-Server, wenn Sie eine echte Anpassung pro Umgebung benötigen (Nr. 2 oben). Wenn Sie es vorziehen, in jeder Umgebung denselben Code bereitzustellen, sollten Sie die Laufzeitkonfiguration (Nr. 3 oben) oder einen Reverse-Proxy (Nr. 4 oben) in Betracht ziehen.

Viel Spaß beim Codieren!

Haben Sie andere Möglichkeiten, wie Sie damit umgehen? Bitte melde dich über die Kommentare.

Cory House ist Autor mehrerer Kurse zu JavaScript, React, Clean Code, .NET und mehr zu Pluralsight. Er ist Principal Consultant bei reactjsconsulting.com, einem Softwarearchitekten von Microsoft MVP, und schult Softwareentwickler auf internationaler Ebene in Front-End-Entwicklungsverfahren. Cory twittert über JavaScript und die Front-End-Entwicklung auf Twitter als @housecor.