I have an existing ASP.Net Core Angular application that used a previous Visual Studio project template where the Web API backend server code and SPA client app are all contained within a single csproj file.
The new Visual Studio 2022 ASP.Net Core Angular application project template as detailed by the following MSDN article uses 2 projects. One csproj for the backend server Web API C# code and another separate esproj (ECMA script project) for the Angular typescript code.
Visual Studio 2022 ASP.Net Core Angular Project Template
So I wanted to convert over to use the new 2 project format and I followed the template example. I got everything working when running the application in Visual Studio which launches the Web API server code and client app code on 2 different urls and proxies between them.
However when the application goes through the continuous integration pipeline the application is published. This uses the publish profiles and in this particular case a standard folder publish profile. When this runs it produces the site with the server code assemblies but no Angular content. When I run the publish locally it completes successfully but with the same result. There is no Angular content. I can see from the build output in Visual Studio that esproj file is definitely being built.
In the old single project setup where was a build target within the crproj file that looked like the following:
<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 -- --configuration=production" />
<!-- Include the newly-built files in the publish output -->
<ItemGroup>
<!-- Adjust the Include path to match the actual output directory of your Angular build -->
<DistFiles Include="$(SpaRoot)\dist\**" />
<ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
<!-- Ensure the files are copied to the wwwroot directory -->
<RelativePath>wwwroot\%(RecursiveDir)%(FileName)%(Extension)</RelativePath>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</ResolvedFileToPublish>
</ItemGroup>
However in the new 2 project setup the csproj has no such build target. So I am guessing it uses some sort of convention to retrieve the Angular content from the dist output path. Like both the MSDN article and example project. I made sure I added the project reference from csproj to the esproj like this:
<ProjectReference Include="..\angularwithasp.client\angularwithasp.client.esproj">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
However the was still no Angular content when doing a publish.
It took a while to work out what the issue was with my project when compared to the template example. However after several hours of going through and trying various changes I realised that the output of the Angular content in the template example was ending up in a directory named after the esproj project name under the standard
distoutput path. This was controlled by theoutputPathproperty in theangular.jsonfile:The output path in the application I was converting over to use the new 2 project setup was set to just dist. Publish must use some sort of convention that looks for a folder with the name of the project most likely based on the project references. And then copies this over.
As it took me a long to work this out and this convention does not appear to be documented anywhere I thought I would post it here as an answer to my own question.
I hope this helps other people.