如何在Angular中显示应用程序版本?

255

如何在Angular应用程序中显示应用程序版本? 版本应从package.json文件中获取。

{
  "name": "angular-app",
  "version": "0.0.1",
  ...
}
在Angular 1.x中,我有这段html代码:
<p><%=version %></p>
在Angular中,它不会将版本号呈现为数字,而是以原样打印输出(使用<%=version %>而不是0.0.1)。

1
如果您有一个构建系统,那么您需要一些Gulp或Grunt插件。据我所知,目前在Angular中还没有这样的机制。 - Angular University
我使用 typescript 编写应用程序,使用 npm start 运行编译,并使用 SystemJS 设置配置。是否有一种方法可以使用其中任何一种来设置版本? - Zbynek
17个回答

431

如果您想在 Angular 应用程序中使用/显示版本号,请按照以下步骤进行操作:

前提条件:

  • 通过 Angular CLI 创建的 Angular 文件和文件夹结构

Angular 6.1(TS 2.9+)到 Angular 11 的步骤:

  1. 在您的/tsconfig.json中(有时还需要在/src/tsconfig.app.json中),启用以下选项(webpack dev server重启后需要执行此步骤):
    "compilerOptions": {
      ...
      "resolveJsonModule": true,
      ...
  1. 然后在你的组件中,例如/src/app/app.component.ts,可以像这样使用版本信息:
    import { version } from '../../package.json';
    ...
    export class AppComponent {
      public version: string = version;
    }

在使用此代码与 Angular 12+ 一起使用时,您可能会遇到以下错误:

Error: Should not import the named export 'version' (imported as 'version') from default-exporting module (only default export is available soon)

在这种情况下,请使用以下代码:

适用于 Angular 12+ 的步骤

  1. 在您的/tsconfig.json中(有时也需要在/src/tsconfig.app.json中)启用以下选项(需要重新启动webpack dev服务器):
    "compilerOptions": {
      ...
      "resolveJsonModule": true,
      "allowSyntheticDefaultImports": true,
      ...
  1. 然后在你的组件中,比如说 /src/app/app.component.ts,像这样使用版本信息:
    import packageJson from '../../package.json';
    ...
    export class AppComponent {
      public version: string = packageJson.version;
    }

还可以在您的 environment.ts 文件中执行第二步,从而使版本信息可从那里访问。

感谢 @Ionaru@MarcoRinck 的帮助。

当进行生产构建时,此解决方案不应包含 package.json 内容-仅包含版本号(使用 Angular 8 和 13 进行了检查)。

请务必检查您生成的 main.#hash#.js 文件!


24
如果有人想知道,这适用于Angular 5和AOT编译。 - Nikola.Lukovic
7
重要提示:重新启动服务器(执行ng serve或npm start)才能生效! - user1884155
21
这个答案不应被接受,因为它会导致安全问题。现在你将你的 package.json 文件包含在浏览器捆绑包中,任何互联网上的人都可以读取你的内部项目配置。请根据 @Ionarus 的解决方案进行编辑。 - Marco Rinck
19
由于Webpack 5引起的问题,Angular 12出现了故障。 - minigeek
7
@sleepwalker 显示的是 Angular 版本而不是 package.json 文件中的版本。 - Mertus
显示剩余26条评论

66

如果你正在使用webpack或angular-cli(它们都使用webpack),你可以在组件中require package.json并显示该prop。

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
  }
}

9
需要注意的是,如果在应用您提供的解决方案后出现“找不到名称 require”的错误,则需要在 tsconfig.app.ts 文件中的“types”属性中添加“node”类型。<< "types": ["node"] >>。已在 Angular v4 中进行测试。 - Tomasz Czechowski
@baio - 我的生产应用程序中已经运行了一年左右的这段代码片段(在生产中运行AOT)。我能以某种方式帮助你调试你的问题吗? - damirsehic
13
尽管这篇文章有些时间了,我还是要指出,这可能会在生产构建中暴露一些构建和开发信息,这对生产环境可能会造成潜在的危害。 - ZetaPR
@ZetaPR 绝对不推荐! - Jimmy Kane
你不应该在package.json文件中存放任何敏感数据,@ZetaPR,那只是一个不好的做法。 - damirsehic
12
从安全角度来看,带有版本号的库是敏感数据。 - Rafiek

46

通过使用tsconfig选项--resolveJsonModule,您可以在Typescript中导入json文件。

在environment.ts文件中:

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

export const environment = {
    VERSION: version,
};

您现在可以在您的应用程序中使用 environment.VERSION


2
@lonaru 导入 package.json 文件时是否存在任何安全隐患?我想知道这样做是否会暴露 package.json 的内容? - tif
4
由于 package.json 没有完全被导入,因此不应该有安全隐患。版本号是唯一最终出现在生产构建中的内容。 - Ionaru
4
使用时,请确保只公开部署生产版本 (ng build --prod);“常规”版本包含整个 package.json(已验证为11.0.5)。 - Janaka Bandara

22

对于这个解决方案,我们是否仍然需要在 tsconfig 文件中更新 "resolveJsonModule": true? - Aakash Goplani
不需要。 - Pierre-Luc

17

version声明为环境变量是一个好主意,这样你就可以在项目的任何地方使用它(特别是在基于版本缓存文件的加载情况下,例如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, { flag: '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;
}

这很好,因为它解决了“不应导入命名导出'版本'”的问题。 - David Wilton

11

Angular CLI用户的最简解决方案。

src/typings.d.ts文件中添加declare module '*.json';,然后在src/environments/environment.ts文件中进行如下配置:

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

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

完成 :)


1
根据你的Angular版本,你可能需要在tsconfig.json中添加"allowSyntheticDefaultImports": true。 - bjornalm

11
在 Angular 12 中,import { version } from '../../package.json';会报错:

./src/environments/environment.ts:10:13-20 - 错误:不应从默认导出模块中导入名为 'version'(作为 'version' 导入)的命名导出(只有默认导出可用)。

如果要继续导入版本而不带来将 package.json 的全部内容都加入构建中的安全隐患,可以这样做:
export const environment = {
  ...
  VERSION: require('../../package.json').version,
};

来自https://github.com/angular/angular-cli/issues/3770#issuecomment-269822722

如果你遇到了一个Cannot find name 'require'错误,请参考https://dev59.com/HVgQ5IYBdhLWcg3wORZJ#43129815https://dev59.com/HVgQ5IYBdhLWcg3wORZJ#54004979


11

Typescript

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>

对于这个解决方案,我们是否仍然需要在 tsconfig 文件中更新 "resolveJsonModule": true? - Aakash Goplani

6
这个答案只适用于Angular 12+,它使用Webpack 5。
根据webpack5文档的说明: 新规范不支持此操作,并会产生警告。请改为:
import { version } from './your-path/package.json';
console.log(version);

使用:

import pkg from './your-path/package.json';
console.log(pkg.version);

此外,您还需要在 tsconfig.json 文件中提供。
"compilerOptions": {
  ...
  "allowSyntheticDefaultImports": true,
  "resolveJsonModule": true,
  ...

1
这在12+中对我有效,但我还必须添加resolveJsonModule - MFB
哦,是的,我忘记了那个,谢谢! - minigeek

5
这个https://github.com/angular/angular-cli/issues/5190有一个有趣的解决方案,使用一个 shell 文件生成 version.ts 文件。@sanjeev 在论坛中提出了类似的解决方案。
这个解决方案使用 Node、JavaScript 和 fs 模块来实现相同的功能。在 Linux 上可以正常工作。应该也可以在 Windows 上工作,因为 Node/fs 是跨平台的...对吧?
  1. add a line to package.json:

    {
      "version": "0.0.1",
      ... 
      "scripts": {
        "version": "node gen_version.js $npm_package_version",
         ...
      },
    ...
    }
    
  2. create gen_version.js (note: it's not typescript)

    var fs = require('fs');
    
    // arg[0]: node path
    // arg[1]: this script's path
    // arg[2]: 1st arg on command line
    console.log('current version: ' + process.argv[2])
    
    path = 'src/environments/version.ts'
    
    script = 'export class Constants {'
    script += '  static readonly version = \'' + process.argv[2] + '\''
    script += '}'
    
    fs.writeFile(path, script, function (err, file) {
      if (err) throw err;
      console.log('file saved:', path);
    });
    
  3. Run it from npm:

    npm run version
    
    > omnitool@0.0.1 version ...
    > node gen_version.js $npm_package_version
    
    current version: 0.0.1
    file saved: src/environments/version.ts
    
  4. use from your app:

    import {Constants} from "../environments/version"
    ...
    console.log('Version:', Constants.version)
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接