Как отобразить версию приложения в Angular?

161

Как мне отобразить версию приложения в угловом приложении? версия должна быть взята из package.jsonфайла

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

В angular 1.x у меня есть этот html:

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

В angular это не отображается как номер версии, а вместо этого просто печатается как есть ( <%=version %>вместо 0.0.1).

Збынек
источник
вам понадобится плагин gulp или grunt, если у вас есть система сборки. в настоящее время в Angular нет никакого механизма AFIK для этого
Angular University
Я использую программу, в которой находится приложение typescript, использую npm startдля запуска компиляции и SystemJSустановки конфигурации. есть ли способ установить версию с помощью любого из них?
Zbynek

Ответы:

280

Если вы хотите использовать / показать номер версии в своем приложении angular, сделайте следующее:

Предпосылки:

  • Angular структура файлов и папок, созданная с помощью Angular CLI

  • TypeScript 2.9 или новее! (Поддерживается начиная с Angular 6.1)

Шаги:

  1. В вашем /tsconfig.json(иногда также необходимо /src/tsconfig.app.json) включите опцию resolveJsonModule (после этого потребуется перезапуск сервера webpack dev):
    "compilerOptions": {
      ...
      "resolveJsonModule": true
      ...
  1. Затем в вашем компоненте, например, /src/app/app.component.tsиспользуйте информацию о версии:
    import { version } from '../../package.json';
    ...
    export class AppComponent {
      public version: string = version;
    }

Также можно выполнить шаг 2 в файле environment.ts, сделав информацию о версии доступной оттуда.

Thx @Ionaru и @MarcoRinck за помощь.

Это решение не будет включать содержимое package.json, только номер версии.
Протестировано с Angular8 / Node10 / TypeScript3.4.3.

Чтобы использовать это решение, обновите свои приложения, потому что в зависимости от содержимого вашего package.json исходное решение может иметь проблемы с безопасностью.

радомить
источник
20
это работает с angular 5 и компиляцией aot, если кому-то интересно
Никола.Лукович
5
Важное примечание: перезапустите сервер (выполните ng serve или npm start снова), чтобы это вступило в силу!
user1884155
2
Этот ответ не следует принимать, поскольку он создает проблему с безопасностью, потому что теперь вы включаете свой package.json в пакет браузера, и теперь все в Интернете могут читать вашу внутреннюю конфигурацию проекта. Пожалуйста, отредактируйте его с помощью решения @Ionarus
Марко Ринк
3
@MarcoRinck: Спасибо, что указали на это. Я мог воспроизвести эту проблему. Не знаю, произошло ли это из-за редактирования ответа в прошлом, но, чтобы убедиться, что никто больше не использует старое решение, я отредактировал ответ и удалил из него проблемный вызов require ().
радомить
3
angular 8 подтвержден
vuhung3990
57

Если вы используете webpack или angular-cli (который использует webpack), вы можете просто потребовать package.json в своем компоненте и отобразить эту опору.

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

И тогда у вас есть компонент

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

  constructor() {
    this.appVersion = appVersion
  }
}
Дислексический
источник
8
Стоит упомянуть, что если кто-то обнаруживает ошибку «Не удается найти имя требуется» после применения вашего решения, тогда необходимо добавить тип «узел» в свойство «типы» в файле tsconfig.app.ts. << "типы": ["узел"] >>. Протестировано в Angular v4
Tomasz
@baio - у меня уже около года работает этот фрагмент кода в моих производственных приложениях (в производственной среде используется AOT). Могу я как-нибудь помочь вам решить вашу проблему?
DyslexicDcuk
5
Несмотря на то, что у этой публикации есть время, я должен указать, что это потенциально может раскрыть некоторую информацию о сборке и разработке в производственных сборках, и это потенциально опасно для производственной среды.
ZetaPR
@ZetaPR точно не рекомендуется!
Джимми Кейн
8
Библиотеки @DyslexicDcuk с номерами версий являются конфиденциальными данными с точки зрения безопасности.
Rafiek
29

Используя опцию tsconfig, --resolveJsonModuleвы можете импортировать файлы json в Typescript.

В файле environment.ts:

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

export const environment = {
    VERSION: version,
};

Теперь вы можете использовать environment.VERSIONв своем приложении.

Ионару
источник
2
@lonaru Есть ли какие-либо последствия для безопасности при импорте файла package.json. Мне интересно, раскрывает ли это каким-то образом содержимое package.json?
tif
2
@tif Не должно быть никаких последствий для безопасности, потому что package.json не полностью импортирован. Версия - это единственное, что попадает в производственную сборку.
Ионару
19

Попытка ответа DyslexicDcuk привела к cannot find name require

Затем чтение раздела «Загрузка дополнительных модулей и другие расширенные сценарии загрузки» на https://www.typescriptlang.org/docs/handbook/modules.html помогло мне решить эту проблему. (Упоминается Гэри здесь https://stackoverflow.com/a/41767479/7047595 )

Используйте приведенное ниже объявление, чтобы потребовать package.json.

declare function require(moduleName: string): any;

const {version : appVersion} = require('path-to-package.json');
Вамси
источник
9

Упрощенное решение для пользователей angular cli.

Добавить declare module '*.json';вsrc/typings.d.ts

А потом src/environments/environment.ts:

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

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

Выполнено :)

박관영
источник
1
Возможно, вам придется добавить "allowSyntheticDefaultImports": trueв файл tsconfig.json в зависимости от версии Angular.
bjornalm
6

Машинопись

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
источник
6

Рекомендуется объявить versionкак переменную среды, чтобы вы могли использовать ее везде в своем проекте. (особенно в случае загрузки файлов для кэширования в зависимости от версии e.g. yourCustomjsonFile.json?version=1.0.0).
Чтобы предотвратить проблемы с безопасностью (как упоминалось в @ZetaPR), мы можем использовать этот подход (в комментарии @sgwatgit)
Короче: мы создаем yourProjectPath \ PreBuild.js файл. Как это:

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

Вышеупомянутый фрагмент создаст новый файл, /src/environments/version.tsсодержащий константу с именем, versionи установит ее по извлеченному значению из package.jsonфайла.

Чтобы запустить содержимое при PreBuild.jsonсборке, мы добавляем этот файл в раздел Package.json->, "scripts": { ... }"как показано ниже. Итак, мы можем запустить проект, используя этот код npm start:

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

Теперь мы можем просто импортировать версию и использовать ее где захотим:

import { version } from '../../../../environments/version';
...
export class MyComponent{
  ...
  public versionUseCase: string = version;
}
Рзассар
источник
4

Я не думаю, что "Angle Bracket Percent" имеет какое-либо отношение к angular1. Вероятно, в вашем предыдущем проекте используется интерфейс к другому API, о котором вы не подозреваете.

Самое простое решение: просто укажите номер версии вручную в файле HTML или сохраните его в глобальной переменной, если вы используете его в нескольких местах:

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

Ваше более сложное решение: запустите этап автоматизации сборки, который извлекает номер версии из вашего файла package.json, а затем перезаписывает ваш файл index.html (или файл js / ts), чтобы включить значение:

  • Можно просто импортировать или потребовать файл package.json, если вы работаете в среде, которая его поддерживает:

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

  • Это также можно сделать в сценарии bash, который читает package.json и затем редактирует другой файл.

  • Вы можете добавить сценарий NPM или изменить сценарий запуска, чтобы использовать дополнительные модули для чтения и записи файлов.
  • Вы можете добавить в конвейер grunt или gulp, а затем использовать дополнительные модули для чтения или записи файлов.
Купер Бэкингем
источник
1
Без подсказки для использования это действительно лучший ответ. Потому что в производственной сборке не будет ненужной / конфиденциальной информации.
Rafiek
<% %>обычно указывает на язык .Net, такой как c #
danwellman
2

Я попытался решить эту проблему несколько иначе, учитывая простоту удобства и ремонтопригодность.

Я использовал сценарий bash, чтобы изменить версию во всем приложении. Следующий сценарий запросит у вас желаемый номер версии, и то же самое применяется во всем приложении.

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

Я сохранил этот сценарий в файле с именем version-manager.sh в корне проекта, а в моем файле package.json я также создал сценарий для его запуска, когда необходимо изменить версию.

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

Наконец, я могу просто изменить версию, выполнив

npm run change-version 

Эта команда изменит версию в шаблоне index.html, а также в файле package.json. Ниже приведены несколько скриншотов из моего существующего приложения.

введите описание изображения здесь

введите описание изображения здесь

введите описание изображения здесь

введите описание изображения здесь

Санджив
источник
-1

Вы можете читать package.json, как и любой другой файл, с http.get вот так:

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
источник