I created an .Net Core Web Api with an Angular ClientApp with the templates from Visual Studio.
When building the project also builds the contained Angular App with the params set in the .csproj <Target> section e.g.
<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>
(This section was auto-generated when creating a new project)
Yet this leaves me no choice which environment.ts file from Angular should be used during a build, which makes building for different deployment targets a bit complicated.
Is there any way to set this file dynamically during build? e.g.
This would ensure that every dotnet build and its corresponding Angular build would have the correct environment values for the api-url, version, etc...
Or is there another (cleaner?) method to use/override environment variables for the Angular App?
These are the values that should be exchanged during build
export const environment = {
production: false,
dataServiceURI: 'https://localhost:5001/data',
version: 'localhost'
};
As localhost:5001 is no viable option in prod for example
I kind of found a solution by manipulating the *.csproj after all.
HINT: To be clear this problem only applies when you created your project with the Visual Studio .Net Core Web Api with Angular Template
which creates a combined web api with clientapp project
After I found out that I could add custom Build Configurations for dotnet build
I added the following lines to the <Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
block:
<Exec WorkingDirectory="$(SpaRoot)" Command="npm run build-prod" Condition="'$(Configuration)' == 'Release'" />
<Exec WorkingDirectory="$(SpaRoot)" Command="npm run build-staging" Condition="'$(Configuration)' == 'Staging'" />
and in package.json add to scripts:
"scripts": {
"build-staging": "ng build --configuration=staging",
"build-prod": "ng build --configuration=production",
},
What it does, is on different build configs set by the Condition
attribute, npm run build
is called with a corresponding/appropriate environment.
Another, perhaps more easy approach, would be to have two build pipelines, one for npm and the angular app and one for the dotnet web api. While doing so, you may want to remove the whole build SPA stuff from the *.csproj otherwise it will build the app twice.
Or just have 2 separate projects in the first place and spare yourself the hassle :)
EDIT:
As pointed out Command="npm run build --configuration=production"
(e.g. build with mutliple params) is not picked up by the CI/CD. So using predefined scripts from package.json is the correct way to go :)