基于.Net Core构建选择正确的Angular环境

时间:2019-04-08 11:59:40

标签: angular asp.net-core-2.2 .net-core-2.2

我使用Angular ClientApp和Visual Studio中的模板创建了.Net Core Web Api。

在构建项目时,还会使用 .csproj 部分中设置的参数来构建包含的Angular App,例如

<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
    <!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build -- --prod" />
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build:ssr -- --prod" Condition=" '$(BuildServerSideRenderer)' == 'true' " />

    <!-- Include the newly-built files in the publish output -->
    <ItemGroup>
      <DistFiles Include="$(SpaRoot)dist\**; $(SpaRoot)dist-server\**" />
      <DistFiles Include="$(SpaRoot)node_modules\**" Condition="'$(BuildServerSideRenderer)' == 'true'" />
      <ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
        <RelativePath>%(DistFiles.Identity)</RelativePath>
        <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
      </ResolvedFileToPublish>
    </ItemGroup>
  </Target>

(此部分是在创建新项目时自动生成的)

然而,这让我没有选择在构建过程中使用Angular的哪个environment.ts文件,这使得为不同部署目标构建的过程有点复杂。

在构建过程中是否可以动态设置此文件?例如

  • appsettings.json 应该使用 environment.ts
  • 构建
  • appsettings.Development.json 应该使用 environment.dev.ts
  • 构建
  • appsettings.Production.json 应该使用 environment.prod.ts
  • 构建

这将确保每个dotnet构建及其对应的Angular构建对于api-url,版本等具有正确的环境值...

还是有另一种(更清洁的方法)为Angular App使用/覆盖环境变量?

这些是在构建过程中应该交换的值

export const environment = {
    production: false,
    dataServiceURI: 'https://localhost:5001/data',
    version: 'localhost'
};

例如,由于localhost:5001在生产中是不可行的选择

2 个答案:

答案 0 :(得分:1)

我毕竟通过操纵* .csproj找到了解决方案。

提示:为清楚起见,此问题仅在使用Visual Studio .Net Core Web Api with Angular Template创建项目时才适用,该项目创建了与clientapp项目组合的网络api

发现可以为dotnet build添加自定义构建配置后,我在<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">块中添加了以下几行:

<Exec WorkingDirectory="$(SpaRoot)" Command="npm run build-prod" Condition="'$(Configuration)' == 'Release'" />
<Exec WorkingDirectory="$(SpaRoot)" Command="npm run build-staging" Condition="'$(Configuration)' == 'Staging'" />

并在package.json中添加到脚本:

"scripts": {
        "build-staging": "ng build --configuration=staging",
        "build-prod": "ng build --configuration=production",
    },

它的作用是在Condition属性设置的不同构建配置上,npm run build是在相应/适当的环境下调用的。

另一种也许更简单的方法是拥有两个构建管道,一个用于npm和angular app,另一个用于dotnet Web api。这样做时,您可能需要从* .csproj中删除整个build SPA内容,否则它将两次构建应用程序。

或者首先只是拥有2个独立的项目,并避免麻烦:)

编辑:

如所指出的,{/ {1}}(例如,使用多重参数构建)没有被CI / CD接收。因此,使用package.json中的预定义脚本是正确的方法:)

答案 1 :(得分:1)

我只想在pjominet的答案中添加一些内容。这是我要在多个环境中工作的漫长搜索路径中的最后一个关键,但这是试图解决相同问题的完整解决方案。

我的目标是为不同的公司使用不同的环境配置,因为该Web应用程序将由不同的公司使用,而只需要很小的更改(启用/禁用模块,更改徽标,更改主题颜色等)。

  1. 配置launchSettings.json(在Web项目中的属性下)。在profiles下添加以下代码:
"Staging": {
 "commandName": "IISExpress",
 "launchBrowser": true,
 "environmentVariables": {
   "ASPNETCORE_ENVIRONMENT": "Staging"
 },
 "applicationUrl": "https://localhost:5001;http://localhost:5000"
}

如果需要的环境名称,其中Staging是名称。这将确保您能够在Visual Studio的Start下选择此配置。

有关更多信息:read this

  1. 在解决方案的根目录中添加您自己的appsettings.Staging.json文件,以用于自定义应用程序设置。尽管这对于本地测试最重要,因为在CI / CD中,您可能需要配置substitutions

  2. 在您的Startup.cs中,添加以下else if块。

app.UseSpa(spa =>
{
    // To learn more about options for serving an Angular SPA from ASP.NET Core,
    // see https://go.microsoft.com/fwlink/?linkid=864501

    spa.Options.SourcePath = "ClientApp";

    if (env.IsDevelopment())
    {
        spa.UseAngularCliServer(npmScript: "start");
    }
    else if (env.EnvironmentName == "TopTechneut")
    {
#if DEBUG
        spa.UseAngularCliServer(npmScript: "start-toptechneutdebug");
#endif
    }
});

请注意#if DEBUG,这是必需的,因为您不想在已部署的环境中执行此操作,但是对于本地运行的angular,您必须调用它,否则最终将显示错误页面。您可能还会注意到,我在环境名称后附加了debug,稍后将进行解释。现在,您必须意识到env.IsDevelopment()是错误的,因此,您必须变通以确保在本地运行应用程序时仍然可以构建和提供有角度的应用程序。

  1. 修改angular.json,在architect => build => configurations下,添加 2 新配置:
"staging": {
  "fileReplacements": [
    {
      "replace": "src/environments/environment.ts",
      "with": "src/environments/environment.toptechneut.ts"
    },
    {
      "replace": "src/assets/img/logo-icon.png",
      "with": "src/assets/img/staging/logo-icon.png"
    },
  ],

  "optimization": true,
  "outputHashing": "all",
  "sourceMap": false,
  "extractCss": true,
  "namedChunks": false,
  "aot": true,
  "extractLicenses": true,
  "vendorChunk": false,
  "buildOptimizer": true,
  "budgets": [
    {
      "type": "initial",
      "maximumWarning": "2mb",
      "maximumError": "5mb"
    }
  ]
},
"stagingdebug": {
  "fileReplacements": [
    {
      "replace": "src/environments/environment.ts",
      "with": "src/environments/environment.toptechneut.ts"
    },
    {
      "replace": "src/assets/img/logo-icon.png",
      "with": "src/assets/img/staging/logo-icon.png"
    },
  ]
}

如果您对angular.json有所了解,您会注意到在staging中我为部署环境进行了配置,我将确保CI / CD会调用它(或在发布应用程序时)通过VS2017)。对于本地测试,我拥有不同的配置stagingdebug,以便它仍然保留源映射,并且能够在本地运行时调试代码。

  1. environment.staging.ts文件夹中添加environments文件,以获取特定于环境的选项。除此之外,read this

  2. 修改您的package.json,在scripts下,我添加了以下脚本:

"start-staging": "ng serve --configuration staging",
"start-stagingdebug": "ng serve --configuration stagingdebug",
"build-staging": "ng build --configuration staging",
"build-stagingdebug": "ng build --configuration stagingdebug",

与此处相同:对于本地开发,我在配置后附加debug

截至目前,您应该能够在Visual Studio中更改为新配置并根据新的环境配置运行!

visual studio choose different config to start

  1. 修改您的.csproj,谢谢。请再次注意,这仅用于发布Web应用程序,而不用于本地调试。
<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
 <Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />

 <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build-core" />
 <Exec WorkingDirectory="$(SpaRoot)" Command="npm run buildprod" Condition="'$(Configuration)' == 'Release'" />
 <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build-staging" Condition="'$(Configuration)' == 'Staging'" />
 <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build:ssr -- --prod" Condition=" '$(BuildServerSideRenderer)' == 'true' " />
  <!--rest below here-->

我修改了我的电话以调用我在script中定义的正确package.json,因为由于某种原因,我的CI在使用pjominet的答案时没有接听其后面的多余命令。

如果使用的是Azure DevOps,则只需将BuildConfiguration变量设置为Staging。如果执行了所有步骤,则应该可以成功构建。

azure devops build config