如何针对不同环境发布 .NET Core + Angular 单页应用程序?

How do I publish a .NET Core + Angular single page app for different environments?

一些额外的上下文:我在 Visual Studio 2019 年使用 Angular project template with ASP.NET Core 创建了一个解决方案。该应用程序有几个不同的环境:DEV、STG 和 Production。 .NET 项目有相应的“appsettings.json”文件(“appsettings.DEV.json”、“appsettings.STG.json”、“appsettings.Production.json”),以及“environment.ts”文件夹中的文件(“environment.DEV.ts”、“environment.STG.ts”、“environment.Production.ts”)。此应用程序将部署到 Windows 服务器上的 IIS,并且我创建了“.pubxml”发布配置文件,针对每个环境的文件夹。

项目模板在 .csproj 文件中生成以下内容:

<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' " />
</Target>

我创建的 .pubxml 文件设置了 ASPNETCORE_ENVIRONMENT 的值,如下所示:

<environmentVariables>
  <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="DEV" />
</environmentVariables>

我还在每个环境的“package.json”文件中为 Angular 客户端应用程序添加了构建脚本:

"scripts": {
  "build-dev": "ng build -c DEV",
  "build-stg": "ng build -c STG",
  "build-prod": "ng build -c Production",
}

但是,我想指定 运行 哪些脚本,具体取决于选择的发布配置文件。我尝试使用以下内容修改“.csproj”文件,但它不起作用。我不知道如何在 .csproj 文件中获取 ASPNETCORE_ENVIRONMENT 的值:

<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-dev" Condition="'$(ASPNETCORE_ENVIRONMENT)' == 'DEV'" />
  <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build-stg" Condition="'$(ASPNETCORE_ENVIRONMENT)' == 'STG'" />
  <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build-production" Condition="'$(ASPNETCORE_ENVIRONMENT)' == 'Production'" />
</Target>

发布整个应用程序的正确方法是什么,同时在“ClientApp”文件夹中为不同环境构建 .NET 应用程序和 Angular 应用程序?

我能够解决我的问题。以下是我为成功发布要部署到 Windows 服务器上的 IIS 的整个 .NET 5 和 Angular 11 单页应用程序所做的更改:

添加了每个环境(DEV、STG 和生产)的解决方案配置:

“.csproj”文件更新如下(使用 $(Configuration) 而不是 $(ASPNETCORE_ENVIRONMENT)):

<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-dev" Condition="'$(Configuration)' == 'DEV'" />
  <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build-stg" Condition="'$(Configuration)' == 'STG'" />
  <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build-production" Condition="'$(Configuration)' == 'Production'" />

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

“package.json”文件的 scripts 部分更新如下:

"scripts": {
  "build-dev": "ng build -c DEV --base-href=/MyAppName/",
  "build-stg": "ng build -c STG --base-href=/MyAppName/",
  "build-prod": "ng build -c Production --base-href=/MyAppName/",
}

在构建 Angular 应用程序的脚本中设置 base-href 值解决了我看到的错误 404 when the app is not published at the site root

最后,我创建的“.pubxml”发布 pofile 被删除,而是我使用 dotnet publish 命令和 -c 配置参数。例如:

  • dotnet publish -c DEV
  • dotnet publish -c STG
  • dotnet publish -c Production

要部署的文件输出到“\MyAppName\bin\{CONFIGURATION}\net5.0\publish\”文件夹。

您可以在每个 pubxml 文件中设置环境配置,如 official documentation:

中所述
<PropertyGroup>
  ...
  <EnvironmentName>Development</EnvironmentName>
</PropertyGroup>

然后为 csproj[=21= 中的每个环境创建一个 PublishRunWebpack... Target 部分] 文件:

<Target Name="PublishRunWebpackDevelopment" AfterTargets="ComputeFilesToPublish" Condition="'$(EnvironmentName)' == 'Development'">
  <Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
  <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build-dev" />
  ...
</Target>

<Target Name="PublishRunWebpackStaging" AfterTargets="ComputeFilesToPublish" Condition="'$(EnvironmentName)' == 'Staging'">
  <Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
  <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build-stg" />
  ...
</Target>

...