Select 正确 Angular 基于 .Net Core 构建的环境
Select correct Angular Environment based on .Net Core build
我使用 Visual Studio 中的模板创建了一个 .Net Core Web Api 和 Angular ClientApp。
构建项目时,还会构建包含的 Angular 应用程序,其参数设置在 .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' " />
<!-- 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 应用程序的 use/override 环境变量是否有另一种(更干净?)方法?
这些是构建期间应该交换的值
export const environment = {
production: false,
dataServiceURI: 'https://localhost:5001/data',
version: 'localhost'
};
因为 localhost:5001 在产品中没有可行的选择
毕竟我通过操作 *.csproj 找到了解决方案。
提示: 需要明确的是,此问题仅在您使用 Visual Studio .Net Core Web Api with Angular Template
创建项目时适用,该项目创建了一个组合网络 api 与 clientapp 项目
在我发现可以为 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
在 corresponding/appropriate 环境中调用。
另一种可能更简单的方法是拥有两个构建管道,一个用于 npm 和 angular 应用程序,一个用于 dotnet web api。这样做时,您可能希望从 *.csproj 中删除整个构建 SPA 内容,否则它将构建应用程序两次。
或者先有 2 个单独的项目,省去麻烦:)
编辑:
正如所指出的那样,Command="npm run build --configuration=production"
(例如使用多个参数构建)未被 CI/CD 拾取。因此,使用 package.json 中的预定义脚本是正确的方法:)
我只是想提供一个end-to-end解决方案,因为我现在将花费一些时间来拯救你:)。
我的目标是为不同的公司提供不同的环境配置,因为 web 应用程序将被不同的公司使用,只需稍作改动(enable/disable 模块、更改徽标、更改主题颜色等)。
- 配置
launchSettings.json
(在属性下的 Web 项目中)。在profiles
下添加如下代码:
"Staging": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Staging"
},
"applicationUrl": "https://localhost:5001;http://localhost:5000"
}
其中 Staging
是您所需的环境名称。这将确保您能够在 Visual Studio.
内 Start
下 select 此配置
更多信息:read this
在自定义应用程序设置项目的根目录中添加您自己的 appsettings.Staging.json
文件。尽管这对于本地测试非常重要,因为在您的 CI/CD 中您可能想要配置 substitutions。如果您确实想在生产中使用特定的 appsettings.Staging.json
,则在服务器上将 ASPNETCORE_ENVIRONMENT
设置为 Staging
(对于配置 => 应用程序设置下的 azure App Service)。
在您的 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 == "Staging")
{
#if DEBUG
spa.UseAngularCliServer(npmScript: "start-stagingdebug");
#endif
}
});
注意 #if DEBUG
,这是必需的,因为您不想在已部署的环境中执行它,但是对于本地 运行ning angular,您必须调用它, 否则你会得到一个错误页面。您可能还注意到,我将 debug
附加到环境名称,我稍后会解释。现在你必须意识到 env.IsDevelopment()
将是错误的,因此你将不得不努力确保你的 angular 应用程序在 运行 在本地运行你的应用程序时仍然会被构建和服务.
- 修改您的
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
,这样它仍然保留源映射,并且我能够在 运行 在本地调试我的代码。
将 environment.staging.ts
文件添加到 environments
文件夹中,用于 environment-specific 选项。更多信息,read this
修改你的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 和 运行 内更改为新配置!
- 修改您的
.csproj
,感谢 pjominet。请再次注意,这仅用于发布您的 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-->
我修改了我的代码以调用我在 package.json
中定义的正确 script
,因为出于某种原因,我的 CI使用 pjominet 的回答。
如果您使用的是 Azure DevOps,只需将 BuildConfiguration
变量设置为 Staging
。如果您按照所有步骤进行操作,那么应该会成功构建。
我使用 Visual Studio 中的模板创建了一个 .Net Core Web Api 和 Angular ClientApp。
构建项目时,还会构建包含的 Angular 应用程序,其参数设置在 .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' " />
<!-- 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 应用程序的 use/override 环境变量是否有另一种(更干净?)方法?
这些是构建期间应该交换的值
export const environment = {
production: false,
dataServiceURI: 'https://localhost:5001/data',
version: 'localhost'
};
因为 localhost:5001 在产品中没有可行的选择
毕竟我通过操作 *.csproj 找到了解决方案。
提示: 需要明确的是,此问题仅在您使用 Visual Studio .Net Core Web Api with Angular Template
创建项目时适用,该项目创建了一个组合网络 api 与 clientapp 项目
在我发现可以为 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
在 corresponding/appropriate 环境中调用。
另一种可能更简单的方法是拥有两个构建管道,一个用于 npm 和 angular 应用程序,一个用于 dotnet web api。这样做时,您可能希望从 *.csproj 中删除整个构建 SPA 内容,否则它将构建应用程序两次。
或者先有 2 个单独的项目,省去麻烦:)
编辑:
正如所指出的那样,Command="npm run build --configuration=production"
(例如使用多个参数构建)未被 CI/CD 拾取。因此,使用 package.json 中的预定义脚本是正确的方法:)
我只是想提供一个end-to-end解决方案,因为我现在将花费一些时间来拯救你:)。
我的目标是为不同的公司提供不同的环境配置,因为 web 应用程序将被不同的公司使用,只需稍作改动(enable/disable 模块、更改徽标、更改主题颜色等)。
- 配置
launchSettings.json
(在属性下的 Web 项目中)。在profiles
下添加如下代码:
"Staging": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Staging"
},
"applicationUrl": "https://localhost:5001;http://localhost:5000"
}
其中 Staging
是您所需的环境名称。这将确保您能够在 Visual Studio.
Start
下 select 此配置
更多信息:read this
在自定义应用程序设置项目的根目录中添加您自己的
appsettings.Staging.json
文件。尽管这对于本地测试非常重要,因为在您的 CI/CD 中您可能想要配置 substitutions。如果您确实想在生产中使用特定的appsettings.Staging.json
,则在服务器上将ASPNETCORE_ENVIRONMENT
设置为Staging
(对于配置 => 应用程序设置下的 azure App Service)。在您的
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 == "Staging")
{
#if DEBUG
spa.UseAngularCliServer(npmScript: "start-stagingdebug");
#endif
}
});
注意 #if DEBUG
,这是必需的,因为您不想在已部署的环境中执行它,但是对于本地 运行ning angular,您必须调用它, 否则你会得到一个错误页面。您可能还注意到,我将 debug
附加到环境名称,我稍后会解释。现在你必须意识到 env.IsDevelopment()
将是错误的,因此你将不得不努力确保你的 angular 应用程序在 运行 在本地运行你的应用程序时仍然会被构建和服务.
- 修改您的
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
,这样它仍然保留源映射,并且我能够在 运行 在本地调试我的代码。
将
environment.staging.ts
文件添加到environments
文件夹中,用于 environment-specific 选项。更多信息,read this修改你的
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 和 运行 内更改为新配置!
- 修改您的
.csproj
,感谢 pjominet。请再次注意,这仅用于发布您的 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-->
我修改了我的代码以调用我在 package.json
中定义的正确 script
,因为出于某种原因,我的 CI使用 pjominet 的回答。
如果您使用的是 Azure DevOps,只需将 BuildConfiguration
变量设置为 Staging
。如果您按照所有步骤进行操作,那么应该会成功构建。