De-mystify the ASP.NET Core Web Application SPA Templates (Angular and React)

Have you ever used one of the ASP.NET Core Web Application SPA Templates (angular or react) and wondered how they work?

Today we'll look at both the Angular and React Templates that ship with ASP.NET Core 5.0 projects and de-mystify the magic behind them.

Although we will be unpacking the Angular and React project templates in this video, the learnings from this can be applied other project types too.

Follow along on youtube or continue reading.

The Basics

As a web developer today, we're quite fortunate to have a host of utilities at our disposal to create & bootstrap our projects.

So angular developers have the Angular CLI, React has Create-React-App and dotnet of course has dotnet new.

These utilities produce robust ready-to-run projects that make it easy for us to start with a working set of code.

I think what makes the dotnet SPA templates interesting is how it leverages UI scaffolding tools together with your dotnet projects to essentially create 2 separate yet connected projects. So thats your UI project (running either angular or react as your front end) and your dotnet project as your API backend.

Why bother you ask?

While these SPA templates make getting started easy; they also tend to obfuscate how the 2 project types work with each other.

Aim of this post is to arm you with the knowledge you need to change and customize it to suit your needs.

This should be particularly helpful when it comes time to setting up your build and deploy pipelines.

Assumptions

You've used other Non SPA templates and generally understand how ASP.NET works (familiarity with Program.cs and Startup.cs).

You're also have some familiarity with either Angular or React.

So, let's get into it..

Steps

Today let's create some SPA projects and explore the code generated to understand how they work.

Create a Project

We'll start by creating a solution called MyApp with 2 projects within it, namely:

  1. MyApp.Angular.App using the ASP.NET Core with Angular template using ASP.NET Core 5.0
  2. MyApp.React.App using the ASP.NET Core with React.js template using ASP.NET Core 5.0

Run them & see it work..

Lets look at the things we know

The Project Structure

  1. The only thing that stands out here is the ClientApp folder. Everything else is pretty stock standard with other ASP.NET Core Projects.
  2. Contents of the ClientApp folder are created using cli tools like @angular/cli or ng for Angular AND create-react-app for React.

Project Package Dependency

Microsoft.AspNetCore.SpaServices.Extensions is the only nuget dependency added.

This package enables the following:

  1. the UseSpa and UseSpaStaticFiles extension methods on the IApplicationBuilder
  2. the AddSpaStaticFiles extension method on the IServiceCollection
  3. the UseAngularCliServer and UseReactDevelopmentServer extension methods on the IWebHostEnvironment

The Startup

The Startup.cs should look similar but a few things stand out

ConfigureServices() has AddSpaStaticFiles extension method. In production, the your Angular or React files will be served from this directory.

Configure() has the UseSpaStaticFiles which serves files configured from the path specified earlier.

Configure() also has the UseSpa extension method. In development this allows us to serve the client via npm using the UseAngularCliServer and UseReactDevelopmentServer extension methods on the IWebHostEnvironment

The Project File

Most of the magic (the fact that things are plumbed together & run) is hidden in the project file. Let's look at it in some detail. Both the Angular and React project files are mostly identical with a few differences based on their individual package.json files.

This first PropertyGroup defines a few key things, namely:

  1. The Root folder for the SPA Project
  2. A directive to exclude node_modules
  3. In the Angular project there's also an option to enable server-side pre-rendering.

Note: At the time of writing this post, "Server-side rendering" is not a supported feature of the react template.

The next ItemGroup ensures we don't publish the SPA source files, but do show them in the project files list.

The next section Target with the DebugEnsureNodeEnv identifier instructs dotnet to complete certain activities before running dotnet build. As you can see, it also has an additional condition attached to it. This section only runs when the configuration is Debug & the node modules folder does not exist. So this would have run the first time we created the project and run it from within visual studio. Within this section, the project template ensures a couple of things.

  • that you have nodejs installed. If it isn't you'll get an error message.
  • it also runs an npm install command which should install all the necessary dependencies of your UI project before building your dotnet project and its dependencies.

The next section Target with the PublishRunWebpack identifier ensures that your projects, both the UI project running angular or react as well as your dotnet project is correctly published. Now when you do setup your build and deploy pipelines, this is the section that you are most likely to change to suit your needs.

As you see here there are a couple of things happening:

  1. It runs an NPM install to get the UI project dependencies
  2. We also run an npm build in production mode.
  3. The third thing we notice (and again this is only for the angular template as it has server side rendering, it won't be in the react project) we run an npm build for server side rendering.

Steps 2 and 3 produce the distribution files that need to be hosted on our web server.

  1. This next section marks those files as valid distribution files. So for the angular project, its the contents within the dist directory. For react its your contents in a directory called build.
  2. Again only for server side rendering we might copy over the node_modules directory (so this won't appear in the react project file)
  3. And lastly by adding the built SPA files to our ResolvedFileToPublish, we can tell the dotnet to include them for publish

The configuration in our dotnet project file together with the code in the Startup.cs ensures that your SPA and API projects work seamlessly, weather you're developing locally or if you are publishing it to your azure app service.

Rohit Lakhanpal

Rohit Lakhanpal

I have worked with a multitude of technologies, specialising in bot and web development, deployment engineering and application life-cycle management.
Melbourne, Australia