VSTS构建 - 在发布阶段替换Angular4环境变量

8

目前我在Angular4中有三个不同的环境:

  • Environment
  • Environment.Debug
  • Environment.Release

enter image description here

现在,在vsts构建流水线中,我已设置了多配置,其中一个定义为调试和发布准备工件:
enter image description here 我正在使用“替换令牌”任务根据调试和发布环境替换变量,然后运行npm installnpm run {either debug or release),然后运行webpack将文件打包到调试或发布环境。
我看到在发布中有一个选项可以替换.json文件(如appsettings.json)中的变量: enter image description here 但问题是当webpack将源代码打包成一个bundle.js时,我认为我无法使用发布来替换环境变量。 我能吗?
我希望能够将调试和发布版本分离。这很简单,我只需重新创建针对调试和发布的不同定义,仅在每个环境中替换变量即可。第二阶段是从构建管道中实际删除替换标记任务,并使用“Release variables”部分来替换在“Release”中设置的每个环境的变量。在webpack将捆绑包编译为js后,如何在Angular中实现呢?

将与构建无关的所有设置从环境文件中获取配置。请参考此处 https://dev59.com/wqrka4cB1Zd3GeqPaDbr#49559443 - David
你可以在json文件中使用任何所需的格式。接下来,根据你选择的格式解析它取决于Angular端(在提供的示例中,它与environment.xx.ts文件具有相同的格式)。 - David
我在思考,如果JSON文件必须具有相同的格式,那么VSTS中的发布阶段是否可以替换变量?例如,对于标准的appsettings.json文件,我们在发布中替换变量的方式如下:https://i.imgur.com/U9zeoJ4.png,对于类似于“ApplicationInsights”这样的结构: { "InstrumentationKey": "xxx" } - sensei
@AmelSalibasic 如果您使用angular-cli,则可以通过ng build --env="envname"自动完成此操作。 - Niladri
@Niladri 我不想让Angular替换变量,我希望VSTS Release替换它们,这样我就不必使用replace token并从Build variable部分中删除变量。这就是为什么我问David在哪里正确地指导了我。现在我只需要知道.json的结构以及配置模型的外观,这样我就可以将json映射到ts类模型。 - sensei
显示剩余2条评论
2个回答

6
最简单、最有效的方法是在您的Angular环境文件中创建令牌,并在发布中使用令牌化器替换那些编译到主包中的令牌。采用这种方法,您现有的代码都不需要更改。
这意味着您将在CI/CD中管理环境变量,而不是在项目中。(您的项目仍需要一个默认的环境文件来本地运行,以及可能用于本地测试的其他文件)
要实现这一点,首先要创建一个用于部署的Angular环境,例如environment.deploy.ts。这是您的构建将使用的(只有一个构建,多个发布)。
以下是environment.deploy.ts的示例:
export const environment = {
  displayLeftPanel: "__env.displayLeftPanel__".toLowerCase() === "true",
  siteName: "__env.siteName__",
  apiUrl: "__env.apiUrl__",
};

我在名称前添加了env.,以确保令牌名称不与包中现有名称冲突。

在发布变量中为每个环境配置这些变量:

env.displayLeftPanel
env.siteName
env.apiUrl

对于您的发布部署,您需要执行以下任务(以下是针对IIS的,但您可以将其用作其他任何内容的路线图)

以下任务解决以下问题:

  • 构建工件通常被压缩在zip文件中,我们无法在zip文件中进行标记化,因此我们首先必须将其解压缩。
  • WebPack捆绑包名称中包含随机ID(例如:main.20f8aa2b341c1c2f6442.bundle.js)。我们需要获取确切的文件名以传递给我们的Tokenizer。
  • 然后我们只需使用诸如“XPath /正则表达式标记化”之类的标记生成器即可

以下是任务:

  • IIS Web应用程序管理
  • 提取文件:*.zip到一个名为unzipped的文件夹中
  • PowerShell:获取主捆绑包名称。类似于:(您可能需要调整路径

    $MainBundleFileName = (get-item $(System.DefaultWorkingDirectory)/main.*.bundle.js).FullName; Write-Host "##vso[task.setvariable variable=MainBundleFileName;]$MainBundleFileName"

  • 标记生成器:对主捆绑包执行变量替换 > $(MainBundleFileName)

  • IIS Web应用程序部署:未压缩的文件夹

1
我找到了一个用于替换zip文件中令牌的任务:https://marketplace.visualstudio.com/items?itemName=solidify-labs.vsts-task-tokenize-in-archive - veuncent

4
你可以从 environment.xx.ts 文件中获取配置值,并将其放入 json 配置文件中,当 Angular 引导时,你将在运行时检索这些值。
发布时,请使用你提到的令牌替换任务来替换 json 文件中的令牌。
JSON 文件的结构并不重要,只要客户端的配置对象结构相同即可(以便于使用)。如果结构不同,只需转换检索到的数据,然后将其分配给你的配置对象即可。 config.json
{
  "envName": "@@envName@@",
  "ApplicationInsights": { "InstrumentationKey": "@@xxx@@" }
}

那么你在 Angular 应用程序中有一个匹配的类。
export class MyConfig
{
  readonly envName: string;
  readonly ApplicationInsights:
  {
      readonly InstrumentationKey: string
  }

一旦你在angular端获取了json数据(称为jsonData),就将其赋值给一个配置对象。

config-service.ts

export let CONFIG: MyConfig;

//Modify jsonData if needed
let t = new MyConfig();
CONFIG = Object.assign(t, jsonData);

component.ts

import {CONFIG} from '../config-service.ts';
//...
//use it
let url = CONFIG.ApplicationInsights.InstrumentationKey;

完整实现

https://dev59.com/wqrka4cB1Zd3GeqPaDbr#49559443


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