Wie kann ich die App-Version in Angular anzeigen?

145

Wie zeige ich die App-Version in einer Winkelanwendung an? Die Version sollte aus der package.jsonDatei entnommen werden

{
  "name": "angular-app",
  "version": "0.0.1",
  ...
}

In Angular 1.x habe ich dieses HTML:

<p><%=version %></p>

Im Winkel wird dies nicht als Versionsnummer gerendert, sondern nur so gedruckt, wie es ist ( <%=version %>anstelle von 0.0.1).

Zbynek
quelle
Sie benötigen ein Schluck- oder Grunz-Plugin, wenn Sie ein Build-System haben. Derzeit gibt es in Angular keinen AFIK-Mechanismus dafür
Angular University
Ich benutze das Programm der App typescript, benutze es npm start, um die Kompilierung auszuführen und SystemJSdie Konfiguration festzulegen. Gibt es eine Möglichkeit, die Version mit einer dieser Optionen festzulegen?
Zbynek

Antworten:

254

Wenn Sie die Versionsnummer in Ihrer Winkel-App verwenden / anzeigen möchten, gehen Sie wie folgt vor:

Voraussetzungen:

  • Angular-Datei- und Ordnerstruktur, die über Angular CLI erstellt wurde

  • TypeScript 2.9 oder höher! (Unterstützt ab Angular 6.1)

Schritte:

  1. In Ihrem /tsconfig.json(manchmal auch notwendig /src/tsconfig.app.json) ermöglicht die resolveJsonModule Option (webpack dev Server - Neustart erforderlich danach):
    "compilerOptions": {
      ...
      "resolveJsonModule": true
      ...
  1. /src/app/app.component.tsVerwenden Sie dann in Ihrer Komponente beispielsweise die Versionsinformationen:
    import { version } from '../../package.json';
    ...
    export class AppComponent {
      public version: string = version;
    }

Es ist auch möglich, Schritt 2 in Ihrer Datei environment.ts auszuführen, um die Versionsinformationen von dort aus zugänglich zu machen.

Danke @Ionaru und @MarcoRinck für die Hilfe.

Diese Lösung enthält nicht den Inhalt von package.json, sondern nur die Versionsnummer.
Getestet mit Angular8 / Node10 / TypeScript3.4.3.

Bitte aktualisieren Sie Ihre Apps, um diese Lösung zu verwenden, da die ursprüngliche Lösung je nach Inhalt Ihres Pakets Sicherheitsprobleme mit sich bringen kann.

Radomeit
quelle
18
Dies funktioniert mit Winkel 5 und aot Zusammenstellung, wenn sich jemand wunderte
Nikola.Lukovic
5
Wichtiger Hinweis: Neustart des Servers (do ng dienen oder npm beginnt wieder) für diese Wirkung zu nehmen!
user1884155
2
@MarcoRinck: Danke, dass du darauf hingewiesen hast. Ich könnte dieses Problem reproduzieren. Ich weiß nicht, ob es auf eine Bearbeitung der Antwort in der Vergangenheit zurückzuführen ist, aber um sicherzustellen, dass niemand mehr die alte Lösung verwendet, habe ich die Antwort bearbeitet und den problematischen Aufruf require () darin entfernt.
Radomeit
3
Winkel 8 bestätigt
vuhung3990
2
Winkel 9 bestätigt
Mike de Klerk
56

Wenn Sie Webpack oder Angular-Cli verwenden (wer verwendet Webpack), können Sie einfach package.json in Ihrer Komponente benötigen und diese Requisite anzeigen.

const { version: appVersion } = require('../../package.json')
// this loads package.json
// then you destructure that object and take out the 'version' property from it
// and finally with ': appVersion' you rename it to const appVersion

Und dann haben Sie Ihre Komponente

@Component({
  selector: 'stack-overflow',
  templateUrl: './stack-overflow.component.html'
})
export class StackOverflowComponent {
  public appVersion

  constructor() {
    this.appVersion = appVersion
  }
}
LegasthenikerDcuk
quelle
8
Es ist erwähnenswert, dass, wenn jemand nach dem Anwenden Ihrer Lösung auf den Fehler "Name kann nicht gefunden werden" stößt, der Typ "Knoten" in der Eigenschaft "Typen" in der Datei tsconfig.app.ts hinzugefügt werden muss. << "types": ["node"] >>. Getestet in Angular v4
Tomasz Czechowski
@baio - Ich habe diesen Codeausschnitt seit ungefähr einem Jahr in meinen Produktions-Apps (AOT in der Produktion). Kann ich Ihnen irgendwie beim Debuggen Ihres Problems helfen?
DyslexicDcuk
5
Obwohl dieser Beitrag einige Zeit hat, muss ich darauf hinweisen, dass dies möglicherweise einige Build- und Entwicklungsinformationen in Produktions-Builds verfügbar macht und dass dies potenziell schädlich für eine Produktionsumgebung ist.
ZetaPR
@ ZetaPR genau nicht zu empfehlen!
Jimmy Kane
7
@ DyslexicDcuk-Bibliotheken mit Versionsnummern sind aus Sicherheitsgründen vertrauliche Daten.
Rafiek
25

Mit der Option tsconfig --resolveJsonModulekönnen Sie JSON- Dateien in Typescript importieren.

In der Datei environment.ts:

import { version } from '../../package.json';

export const environment = {
    VERSION: version,
};

Sie können jetzt environment.VERSIONin Ihrer Anwendung verwenden.

Ionaru
quelle
1
@lonaru Gibt es Sicherheitsaspekte beim Importieren der Datei package.json? Ich frage mich, ob dies den Inhalt von package.json auf irgendeine Weise enthüllt.
Bis
1
@tif Es sollten keine Auswirkungen auf die Sicherheit auftreten, da die Datei package.json nicht vollständig importiert wird. Die Version ist das einzige, was im Produktions-Build landet.
Ionaru
19

Der Versuch, DyslexicDcuks Antwort zu versuchen, führte dazu cannot find name require

Das Lesen des Abschnitts "Optionales Laden von Modulen und andere erweiterte Ladeszenarien" in https://www.typescriptlang.org/docs/handbook/modules.html hat mir dabei geholfen, dieses Problem zu lösen. (Erwähnt von Gary hier https://stackoverflow.com/a/41767479/7047595 )

Verwenden Sie die folgende Deklaration, um package.json zu benötigen.

declare function require(moduleName: string): any;

const {version : appVersion} = require('path-to-package.json');
Vamsi
quelle
8

Einfache Lösung für Angular Cli-Benutzer.

Add declare module '*.json';onsrc/typings.d.ts

Und dann weiter src/environments/environment.ts:

import * as npm from '../../package.json';

export const environment = {
  version: npm.version
};

Getan :)

박관영
quelle
1
"allowSyntheticDefaultImports": trueAbhängig von Ihrer Angular-Version müssen Sie möglicherweise zu tsconfig.json hinzufügen .
Björnalm
6

Es ist eine gute Idee, versionals Umgebungsvariable zu deklarieren, damit Sie sie überall in Ihrem Projekt verwenden können. ( Insbesondere beim Laden von Dateien, die basierend auf der Version zwischengespeichert werden sollen e.g. yourCustomjsonFile.json?version=1.0.0)
Um Sicherheitsprobleme zu vermeiden (wie bei @ZetaPR erwähnt) , können wir diesen Ansatz verwenden (im Kommentar von @sgwatgit).
Kurz gesagt: Wir erstellen yourProjectPath \ PreBuild.js Datei. So was:

const path = require('path');
const colors = require('colors/safe');
const fs = require('fs');
const dada = require.resolve('./package.json');
const appVersion = require('./package.json').version;

console.log(colors.cyan('\nRunning pre-build tasks'));

const versionFilePath = path.join(__dirname + '/src/environments/version.ts');

const src = `export const version = '${appVersion}';
`;
console.log(colors.green(`Dada ${colors.yellow(dada)}`));

// ensure version module pulls value from package.json
fs.writeFile(versionFilePath, src, { flat: 'w' }, function (err) {
if (err) {
    return console.log(colors.red(err));
}

console.log(colors.green(`Updating application version         
${colors.yellow(appVersion)}`));
console.log(`${colors.green('Writing version module to 
')}${colors.yellow(versionFilePath)}\n`);
});

Über dem Snippet wird eine neue Datei erstellt, /src/environments/version.tsdie eine Konstante mit dem Namen enthält, versionund durch den aus der package.jsonDatei extrahierten Wert festgelegt .

Um den Inhalt von PreBuild.jsonon build auszuführen , fügen wir diese Datei wie folgt in den Abschnitt Package.json-> "scripts": { ... }"ein. Also wir Projekt mit diesem Code ausführen können: npm start:

{
  "name": "YourProject",
  "version": "1.0.0",
  "license": "...",
  "scripts": {
    "ng": "...",
    "start": "node PreBuild.js & ng serve",
  },...
}

Jetzt können wir einfach die Version importieren und verwenden, wo immer wir wollen:

import { version } from '../../../../environments/version';
...
export class MyComponent{
  ...
  public versionUseCase: string = version;
}
Rzassar
quelle
5

Typoskript

import { Component, OnInit } from '@angular/core';
declare var require: any;

@Component({
  selector: 'app-version',
  templateUrl: './version.component.html',
  styleUrls: ['./version.component.scss']
})
export class VersionComponent implements OnInit {
  version: string = require( '../../../../package.json').version;

  constructor() {}

  ngOnInit() {

  }
}

HTML

<div class="row">
    <p class="version">{{'general.version' | translate}}: {{version}}</p>
</div>
vrbsm
quelle
4

Ich glaube nicht, dass "Angle Bracket Percent" etwas mit angle1 zu tun hat. Dies ist wahrscheinlich eine Schnittstelle zu einer anderen API, von der Sie nicht wissen, dass sie in Ihrem vorherigen Projekt verwendet wird.

Ihre einfachste Lösung: Listen Sie die Versionsnummer einfach manuell in Ihrer HTML-Datei auf oder speichern Sie sie in einer globalen Variablen, wenn Sie sie an mehreren Stellen verwenden:

<script>
  var myAppVersionNumber = "0.0.1";
</script>
...
<body>
  <p>My App's Version is: {{myAppVersionNumber}}</p>
</body>

Ihre schwierigere Lösung: Führen Sie einen Build-Automatisierungsschritt aus, der die Versionsnummer aus Ihrer package.json-Datei extrahiert und anschließend Ihre index.html-Datei (oder js / ts-Datei) neu schreibt, um den Wert einzuschließen:

  • Könnte einfach die Datei package.json importieren oder benötigen, wenn Sie in einer Umgebung arbeiten, die dies unterstützt:

    var version = require("../package.json").version;

  • Dies kann auch in einem Bash-Skript erfolgen , das die Datei package.json liest und dann eine andere Datei bearbeitet.

  • Sie können ein NPM-Skript hinzufügen oder Ihr Startskript ändern, um zusätzliche Module zum Lesen und Schreiben von Dateien zu verwenden.
  • Sie können Ihrer Pipeline Grunzen oder Schlucken hinzufügen und dann zusätzliche Module zum Lesen oder Schreiben von Dateien verwenden.
Cooper Buckingham
quelle
Ohne den zu verwendenden Tipp ist dies eigentlich die beste Antwort. Weil der Produktionsaufbau keine unnötigen / sensiblen Informationen enthält.
Rafiek
<% %>zeigt normalerweise eine .Net-Sprache wie c # an
danwellman
2

Ich habe versucht, dies auf eine etwas andere Art und Weise zu lösen, auch unter Berücksichtigung der Benutzerfreundlichkeit und Wartbarkeit.

Ich habe das Bash-Skript verwendet, um die Version in der gesamten Anwendung zu ändern. Das folgende Skript fragt Sie nach der gewünschten Versionsnummer und diese wird in der gesamten Anwendung angewendet.

#!/bin/bash
set -e

# This script will be a single source of truth for changing versions in the whole app
# Right now its only changing the version in the template (e.g index.html), but we can manage
# versions in other files such as CHANGELOG etc.

PROJECT_DIR=$(pwd)
TEMPLATE_FILE="$PROJECT_DIR/src/index.html"
PACKAGE_FILE="$PROJECT_DIR/package.json"

echo ">> Change Version to"
read -p '>> Version: ' VERSION

echo
echo "  #### Changing version number to $VERSION  ####  "
echo

#change in template file (ideally footer)
sed -i '' -E "s/<p>(.*)<\/p>/<p>App version: $VERSION<\/p>/" $TEMPLATE_FILE
#change in package.json
sed -i '' -E "s/\"version\"\:(.*)/\"version\"\: \"$VERSION\",/" $PACKAGE_FILE


echo; echo "*** Mission Accomplished! ***"; echo;

Ich habe dieses Skript in einer Datei mit dem Namen version-manager.sh im Stammverzeichnis des Projekts gespeichert und in meiner Datei package.json ein Skript erstellt, um es auszuführen, wenn die Version geändert werden muss.

"change-version": "bash ./version-manager.sh"

Schließlich kann ich die Version einfach durch Ausführen ändern

npm run change-version 

Dieser Befehl ändert die Version in der Vorlage index.html und auch in der Datei package.json. Es folgen die wenigen Screenshots aus meiner vorhandenen App.

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Sanjeev
quelle
0

Sie können package.json wie jede andere Datei lesen, mit http.get wie folgt:

import {Component, OnInit} from 'angular2/core';
import {Http} from 'angular2/http';

@Component({
    selector: 'version-selector',
    template: '<div>Version: {{version}}</div>'
})

export class VersionComponent implements OnInit {

    private version: string;

    constructor(private http: Http) { }

    ngOnInit() {
        this.http.get('./package.json')
            .map(res => res.json())
            .subscribe(data => this.version = data.version);
    }
}
Presari
quelle