Der Mensch ist bemüht stets alles richtig zu machen… Meistens. Auch wenn Zeit- und Budgetdruck da ist, früher oder später wird es Zeit alles aufzuräumen.
Aktueller Fall:
Eine Anwendung, die mehrere Heroku Instanzen für die unterschiedliche Development-, Staging- und Produktions-Umgebungen durchläuft, mit einem Node.js Express / AngularJS Frontend und einem Java Backend.
Beim Development und Deployment in der Cloud ist hohe Flexibilität genauso gewünscht wie Hochverfügbarkeit und einfache Skalierbarkeit. Aber wie lässt sich eine Software über unterschiedliche Plattformen und Infrastrukturen „bewegen“, ohne dabei ständig an die jeweiligen Voraussetzungen für das Deployment und den Betrieb angepasst zu werden? Ohne jedes Mal an einer appConfig.js oder web.js was ändern zu müssen?
Es wäre doch so schön, wenn die API base URL-s, Datenbank Resourcen, und andere, von der Laufzeit Umgebung anhängige Konstanten einfach ausgelesen werden könnten.
Der Weg mit if (isLocalhost) funktioniert nur begrenzt und auch nicht wirklich wartungsfrei.
Zur Verfügung stehen folgende Mittel:
⦁ Heroku Config Variablen:
Die Variable BACKEND ändert sich natürlich von Umgebung zu Umgebung.
- Node.js Express und der Task Runner grunt
- AngularJS mit der Komponente ‚constant‘
Aufgabenstellung:
Die aktuell gültige API base URL für die verwendeten Webservices per Konfiguration auslesen und in AngularJS verwenden.
Der Weg von der Heroku config Variable bis zu der gewünschten AngularJS Modul dauert etwa 15 Minuten – diese kann man sicher irgendwo im Budget unterbringen:
Durchführung:
Auf die Heroku config Variablen kann mit process.env.ENV zugegriffen werden – aber leider nicht direkt in AngularJS. Mit dem Problem steht man nicht alleine da, es gibt inzwischen mehrere elegante Lösungen:
- mit webpack (1)
- via REST (2) oder
- mit grunt-ng-constant (3)
Letzteres wollen wir hier kurz vorstellen.
Grunt-ng-constant
Mit dem Grunt Plugin grunt-ng-constant können wir Konstanten für die verschiedenen Umgebungen definieren und in unseren Grunt tasks verwenden.
Zum Installieren des Plugins benutzen wir npm:
Zu der Konfiguration brauchen wir 3 Schritte, öffnen wir dazu unsere Gruntfile.js:
1. in dem Abschnitt „ngconstant“ beschreiben wir den Weg, wie die Generierung der neuen Konfigurationsdatei zu erfolgen hat:
a.) Die Datei soll als client/js/backendconfig.js erstellt werden
b.) und die Konstante aus dem process.env.BACKEND auslesen
2. Anschließend den Task laden und ausführen:
Mit diesen Schritten ist die Konfiguration abgeschlossen.
Nachdem wir unseren Grunt-Task ausgeführt haben, entsteht das frisch generierte AngularJS Modul etwa so aus:
Die Datei wird nach jedem grunt Aufruf neu erstellt, somit steht unter „apiEndPoint“ immer die aktuell verwendete process.end.BACKEND als String drin.
(Hinweis bei Verwendung von Heroku Pipelines: hier muss darauf geachtet werden, dass der gewählte grunt Task tatsächlich auch ausgeführt wird)
3. Die Verwendung ist denkbar einfach –
Und damit ist das Ziel erreicht.
1: https://github.com/AngularClass/angular2-webpack-starter/wiki/How-to-pass-environment-variables%3F