Comment afficher la version de l'application dans Angular?

146

Comment afficher la version de l'application dans une application angulaire? la version doit être extraite du package.jsonfichier

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

Dans angular 1.x, j'ai ce html:

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

En angulaire, ce n'est pas rendu en tant que numéro de version, mais simplement imprimé tel quel ( <%=version %>au lieu de 0.0.1).

Zbynek
la source
vous avez besoin d'un plugin gulp ou grunt, si vous avez un système de construction. il n'y a actuellement aucun mécanisme AFIK dans Angular pour cela
Angular University
J'utilise le programme dans l'application typescript, j'utilise npm startpour exécuter la compilation et SystemJSpour définir la configuration. existe-t-il un moyen de définir la version en utilisant l'un de ces éléments?
Zbynek

Réponses:

255

Si vous souhaitez utiliser / afficher le numéro de version dans votre application angulaire, procédez comme suit:

Conditions préalables:

  • Structure de fichiers et de dossiers angulaire créée via Angular CLI

  • TypeScript 2.9 ou version ultérieure! (Pris en charge à partir d'Angular 6.1)

Pas:

  1. Dans votre /tsconfig.json(parfois également nécessaire /src/tsconfig.app.json), activez l'option ResolutionJsonModule (redémarrage du serveur de développement Webpack requis par la suite):
    "compilerOptions": {
      ...
      "resolveJsonModule": true
      ...
  1. Ensuite, dans votre composant, /src/app/app.component.tsutilisez par exemple les informations de version:
    import { version } from '../../package.json';
    ...
    export class AppComponent {
      public version: string = version;
    }

Il est également possible de faire l'étape 2 dans votre fichier environment.ts, en rendant les informations de version accessibles à partir de là.

Thx @Ionaru et @MarcoRinck pour aider.

Cette solution n'inclura pas le contenu de package.json, uniquement le numéro de version.
Testé avec Angular8 / Node10 / TypeScript3.4.3.

Veuillez mettre à jour vos applications pour utiliser cette solution car selon le contenu de votre package.json, la solution d'origine peut impliquer des problèmes de sécurité.

radomeit
la source
18
cela fonctionne avec angular 5 et aot compilation si quelqu'un se demandait
Nikola.Lukovic
5
Remarque importante: redémarrez votre serveur (do ng serve ou npm start again) pour que cela prenne effet!
user1884155
2
@MarcoRinck: Merci de l'avoir signalé. Je pourrais reproduire ce problème. Je ne sais pas si cela est dû à une modification de la réponse dans le passé, mais pour m'assurer que personne n'utilise plus l'ancienne solution, j'ai modifié la réponse et supprimé l'appel problématique require ().
radomeit
3
angular 8 confirmé
vuhung3990
2
Angular 9 confirmé
Mike de Klerk le
56

Si vous utilisez webpack ou angular-cli (qui utilise webpack), vous pouvez simplement exiger package.json dans votre composant et afficher cet accessoire.

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

Et puis vous avez votre composant

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

  constructor() {
    this.appVersion = appVersion
  }
}
DyslexicDcuk
la source
8
Il vaut la peine de mentionner que si quelqu'un rencontre l'erreur "Cannot find name require" après avoir appliqué votre solution, il doit alors ajouter le type "node" à l'intérieur de la propriété "types" dans le fichier tsconfig.app.ts. << "types": ["node"] >>. Testé en Angular v4
Tomasz Czechowski
@baio - J'ai cet extrait de code en cours d'exécution dans mes applications de production depuis environ un an maintenant (exécutant AOT en production). Puis-je vous aider à résoudre votre problème d'une manière ou d'une autre?
DyslexicDcuk
5
Malgré ce post, je dois souligner que cela exposerait potentiellement certaines informations de construction et de développement dans les versions de production et que cela est potentiellement dangereux pour un environnement de production.
ZetaPR
@ZetaPR n'est absolument pas recommandé!
Jimmy Kane
7
Les bibliothèques @DyslexicDcuk avec des numéros de version sont des données sensibles du point de vue de la sécurité.
Rafiek
25

En utilisant l'option tsconfig, --resolveJsonModulevous pouvez importer des fichiers json dans Typescript.

Dans le fichier environment.ts:

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

export const environment = {
    VERSION: version,
};

Vous pouvez maintenant utiliser environment.VERSIONdans votre application.

Ionaru
la source
1
@lonaru Y a-t-il des implications de sécurité lors de l'importation du fichier package.json. Je me demande si cela expose d'une manière ou d'une autre le contenu de package.json?
tif
1
@tif Il ne devrait y avoir aucune implication de sécurité car le package.json n'est pas entièrement importé. La version est la seule chose qui se termine dans la version de production.
Ionaru
19

Essayer la réponse de DyslexicDcuk a abouti à cannot find name require

Ensuite, la lecture de la section `` Chargement de module optionnel et autres scénarios de chargement avancés '' dans https://www.typescriptlang.org/docs/handbook/modules.html m'a aidé à résoudre ce problème. (Mentionné par Gary ici https://stackoverflow.com/a/41767479/7047595 )

Utilisez la déclaration ci-dessous pour exiger package.json.

declare function require(moduleName: string): any;

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

Solution simpliste pour les utilisateurs angulaires de cli.

Ajouter declare module '*.json';sursrc/typings.d.ts

Et puis sur src/environments/environment.ts:

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

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

Terminé :)

박관영
la source
1
Vous devrez peut-être ajouter "allowSyntheticDefaultImports": trueà votre tsconfig.json en fonction de votre version angulaire.
bjornalm
6

C'est une bonne idée de déclarer versioncomme variable d'environnement afin que vous puissiez l'utiliser partout dans votre projet. (spécialement en cas de chargement de fichiers à mettre en cache en fonction de la version e.g. yourCustomjsonFile.json?version=1.0.0)
Afin d'éviter les problèmes de sécurité (comme @ZetaPR l'a mentionné), nous pouvons utiliser cette approche (sur le commentaire de @sgwatgit)
En bref: nous créons un yourProjectPath \ PreBuild.js fichier. Comme ça:

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`);
});

L'extrait ci-dessus créera un nouveau fichier /src/environments/version.tsqui contient une constante nommée versionet la définira par valeur extraite du package.jsonfichier.

Afin d'exécuter le contenu de la PreBuild.jsonconstruction, nous ajoutons ce fichier dans la section Package.json-> "scripts": { ... }"comme suit. Nous pouvons donc exécuter le projet en utilisant ce code npm start::

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

Maintenant, nous pouvons simplement importer la version et l'utiliser où nous voulons:

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

Manuscrit

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
la source
4

Je ne pense pas que "Angle Bracket Percent" ait quoi que ce soit à voir avec angular1. Il s'agit probablement d'une interface vers une autre API dont vous ne réalisez pas qu'elle est utilisée dans votre projet précédent.

Votre solution la plus simple: listez simplement le numéro de version manuellement dans votre fichier HTML ou stockez-le dans une variable globale si vous l'utilisez à plusieurs endroits:

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

Votre solution la plus difficile: exécutez une étape d'automatisation de la construction qui extrait le numéro de version de votre fichier package.json, puis réécrit votre fichier index.html (ou fichier js / ts) pour inclure la valeur:

  • Pourrait simplement importer ou exiger le fichier package.json, si vous travaillez dans un environnement qui le prend en charge:

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

  • Cela pourrait également être fait dans un script bash qui lit le package.json, puis édite un autre fichier.

  • Vous pouvez ajouter un script NPM ou modifier votre script de démarrage pour utiliser des modules supplémentaires pour lire et écrire des fichiers.
  • Vous pouvez ajouter grunt ou gulp à votre pipeline, puis utiliser des modules supplémentaires pour lire ou écrire des fichiers.
Cooper Buckingham
la source
Sans la pointe à utiliser, c'est en fait la meilleure réponse. Parce qu'il n'y aura pas d'informations inutiles / sensibles dans la version de production.
Rafiek
<% %>indique généralement un langage .Net comme c #
danwellman
2

J'ai essayé de résoudre ce problème d'une manière un peu différente, compte tenu également de la facilité d'utilisation et de la maintenabilité.

J'ai utilisé le script bash pour changer la version dans toute l'application. Le script suivant vous demandera le numéro de version souhaité, et la même chose est appliquée dans toute l'application.

#!/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;

J'ai enregistré ce script dans un fichier nommé version-manager.sh à la racine du projet, et dans mon fichier package.json, j'ai également créé un script pour l'exécuter lorsqu'il est nécessaire de modifier la version.

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

Enfin, je peux simplement changer la version en exécutant

npm run change-version 

Cette commande changera la version dans le modèle index.html et également dans le fichier package.json. Voici les quelques captures d'écran prises à partir de mon application existante.

entrez la description de l'image ici

entrez la description de l'image ici

entrez la description de l'image ici

entrez la description de l'image ici

Sanjeev
la source
0

Vous pouvez lire package.json comme n'importe quel autre fichier, avec http.get comme ceci:

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
la source