.NET CLI contains templates for ASP.NET Core with Angular or React.
dotnet new
...
ASP.NET Core with Angular angular [C#] Web/MVC/SPA
ASP.NET Core with React.js react [C#] Web/MVC/SPA
ASP.NET Core with React.js and Redux reactredux [C#] Web/MVC/SPA
...
What if you want to use Vue.js or any other setup?
Or want to host spa application inside ASP.NET Core app only in production and use VS Code and other dev server while developing?
I frequently have these requirements / preferences
First two points are obvious. Just create separate projects and use separate dev tools. Third point is quite easy as well.
When you build your client app (Angular, React, Vue at least) you get dist or build directory with index.html and some .js and .css files.
What you need to do to deploy them together is just
I created a vue app inside ASP.NET Core app like in the picture below
Just add necessary (npm) commands to be run (.csproj file)
<Target Name="Build client" BeforeTargets="ComputeFilesToPublish">
<Exec Command="npm install" WorkingDirectory="vue-client"></Exec>
<Exec Command="npm run build" WorkingDirectory="vue-client"></Exec>
</Target>
This depends on where the client output files are located
Provide static files from wwwroot
// Startup.Configure()
app.UseStaticFiles();
Set client app output dir to wwwroot (package.json)
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build --dest ../wwwroot",
"lint": "vue-cli-service lint"
},
It's also possible to use Copy task to copy files from dist to wwwroot.
Provide static files from client app output directory (dist)
// Startup.Configure()
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "vue-client", "dist"))
});
Don't publish client app source files, but copy output files
<ItemGroup>
<Content Remove="vue-client\**" />
</ItemGroup>
<ItemGroup>
<None Update="vue-client\dist\**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
Add MapFallbackToFile to endpoints configuration
// Startup.Configure()
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
// route non-api urls to index.html
endpoints.MapFallbackToFile("/index.html");
});