Selbst bei einfachstem Test- und Release-Vorgehen sollte immer klar sein welche Version der Anwendung man gerade vor sich hat. Hilfreich ist es dabei einen Zeitstempel und/oder die aktuelle Version innerhalb der Anwendung sichtbar zu machen.
Version
Die Version unserer Anwendung finden wir in unser package.json. Diese Datei ist aber natürlich nicht Teil unseres ausgelieferten Bundles. Diese Datei beim build einfach zu kopieren und somit verfügbar zu machen mag einfach sein, offenbart aber potenziellen Angreifern eine Vielzahl von Informationen über unser Projekt und dessen Abhängigkeiten. Stattdessen importieren wir in unserer Komponente die package.json und ermöglichen unserem TypeScript Compiler die Version zu extrahieren:
import {version} from '../../package.json';
...
@Component({})
export class AppComponent {
version: string;
Damit TypeScript diesen Zugriff auf eine einfache JSON-Datei per Import erlaubt, reicht es aus in unserer tsconfig folgenden Eintrag zu ergänzen:
"resolveJsonModule": true,
Zeitstempel
Der Zeitstempel stellt tatsächlich eine größere “Herausforderung” dar. Unser Vorgehen: ein Eintrag in unserer Environment soll soll dazu dienen den Zeitstempel in der Anwendung verfügbar zu machen. Damit lässt sich eine Ausgabe in unserer Komponente ganz einfach realisieren
this.version = `${version} - ${environment.buildTime}`
Unsere environments bereiten wir mit einem entsprechenden Eintrag vor:
export const environment = {
buildTime: '',
...
Diese Variable muss aber nun natürlich beim Build auch gesetzt werden. Dazu verwenden wir ein NPM-Tool:
replace-in-file – npm (npmjs.com)
Damit können wir mittels node-Script, einen beliebigen Text-Ersatz innerhalb von Dateien ausführen. Ein entsprechendes Script könnte so aussehen. Dabei ermöglichen wir auch das “zurücksetzen” auf einen Default Wert. Hintergrund: wir wollen keine unnötigen Dateiänderungen in unserem Versionskontrollsystem nach einem Build:
let replace = require("replace-in-file");
let buildTime = new Date().toISOString();
let revert = process.argv[2];
const options = {
files: "src/environments/*.ts",
allowEmptyPaths: false,
from: /buildTime.*/g,
to: `buildTime: '${revert ? '' : buildTime}',`
};
try {
replace.sync(options);
} catch (error) {
console.error("Error while setting build time:", error);
}
Anpassung an unserem npm-build-script:
"build": "node ./replace.build.js
&& ng build --prod --base-href .
&& node ./replace.build.js revert",
…und schon landet eine kleine nette Info in unserer Anwendung: