YesSpa allows adding single page applications (SPA) to ASP.NET Core web projects. Currently supported SPAs are:
- angular/cli, version 6 and up
- create-react-app (tested with typescript version)
The main difference is the approach for SPA tooling. JavaScript services provide sophisticated tooling over SPA. Internally they are setting up proxies to transfer data between the web server and a CLI tool (create react app or angular-cli). Effectively JavaScript services almost completely hide the fact that you are running another development server on the SPA level. Thanks to that you have client code debugging right in Visual Studio and smooth experience. Still the 'native' CLIs provide the same functionality and I believe that JavaScript services make things over-complicated.
YesSpa is different: basically it assumes that you have the knowledge of SPA CLIs and using them for development. YesSpa comes into play only when you need to deploy the SPA along with the ASP.Net host application. It performs the SPA build and embedds the result files into .Net Core assembly. Then it serves HTTP requests for that files from ASP.Net Core pipeline.
Unlike standard SPA templates coming with ASP.NET Core, YesSpa designed so that the SPAs are located in individual class libraries and embedded as resources in result dll files. A web application can serve multiple SPAs.
During development you use process and tools 'native' to single page applications, i.e. serve the SPA in development host with angular/cli or create-react-app. When building SPA on a CI server YesSpa launches build tasks for SPAs and embedds result files in dll resources. You do not need to copy package files manually.
- Only one SPA per module is allowed. The SPA should be created right inside of the module. It means that SPA's package.json should be located in the same folder as csproj file of the module (check samples for more details).
- YesSpa assumes that you keep default build folders. Angular/cli puts result files in dist folder and create-react-app puts result files in build folder.
- There is no debugger support in Visual Studio but you can use other tools like Chrome debugger and Visual Studio Code.
- You should use CORS in development evironment for API access (that depends on configuration but typically if API hosted by the same app as SPA you should configure the cross-origin access).
- No support for server-side rendering (check JavaScript services if you need that).
cd .\samples\aspnetcore\AspNetCore.Host.Web\
.\run-dev-embedded.cmd
- Open the solution in Visual Studio
- Set samples/aspnetcore/AspNetCore.Host.Web as startup project
- Run the project
The following needed in order to use YesSpa in your application:
- Create/configure the SPA module
- Configure host project (usually an MVC project in your solution)
- Configure SPA build
- Add another .NET standard library to your solution
- Create client appliation using angular/cli or create-react-app in that folder. Important: do not use a subfolder like ClientApp or something like that beause YesSpa's convention is to use the root library folder for building and serving SPA.
- Reference YesSpa.Client.Targets NuGet package in the SPA module.
- Add reference to your SPA module in the host app
- Add reference to YesSpa.AspNetCore NuGet package
- Add the following to Startup.ConfigureServices()
services.AddYesSpa(builder =>
{
builder.AddSpa(Assembly.GetAssembly(typeof(ClientAppModuleReact)), "/",
"/.Modules/ClientApp.React/build");
});
- Add the following to Startup.Configure()
app.UseYesSpa();
This should be the last middleware in ASP.NET Core middleware chain. The call configures middleware serving SPA and tells YesSpa how to get access to the embedded SPA files:
- "/" - means that SPA will be served at root URL
- "/.Modules/ClientApp.React/build" - path in resources to embedded package (in this case ClientApp.React is name of assembly containing SPA).
When you reference YesSpa.Client.Targets in an SPA module it adjusts the build process so that MSBuild executes tasks for building the SPA and embedding result files into the SPA assembly. You enable the SPA build by passing YesSpaEnabled=true to MSBuild.
You can perform that in two ways: set the property explicitly in csproj files (like in the sample application) and pass the property in dotnet build command line. Common SPA build settings:
YesSpaEnabled=true
Should be set to set to true to enable whole YesSpa during the build.
YesSpaSkipSpaBuild=true
Pass to skip SPA build. Use with caution because if there's no SPA build files they will not be embedded in assembly.
You have to build SPA manually when using this option (e.g. 'ng biuld').
YesSpaSkipNpmInstall=true
Pass to skip npm install call during the build. Use with caution because if there's no npm packages installed SPA build will fail.
You have to update NPM packages manually when using this option (e.g. 'npm install').
There are also framework-specific settings that should be set in order to build the SPA.
YesSpaBuildTools=angular
Should be set to enable angular toolchain.
YesSpaAngularBaseHref=base_href
Example: YesSpaAngularBaseHref='/angular/'
This is basically the value to be set as base href in index.html.
Check details at angular cli wiki
YesSpaAngularDeployUrl=embedded_path
Example: YesSpaAngularDeployUrl='/.Modules/AspNetCore.ClientApp.Angular/dist/aspnetcore-clientapp-angular/'
this is angular-cli deploy-url option.
The path convention is the following: '.Modules/<SPA_MODULE_NAMESPACE>/<EMBEDDED_PATH>'
YesSpaAngularConfiguration=configuration_name
Example: YesSpaAngularConfiguration='dev_embedded'
this is angular-cli configuration option (FKA environment).
Check details at angular cli wiki
YesSpaBuildTools=react
Should be set to enable react toolchain.
For React application you have to configure PUBLIC_URL in .env file
For example:
PUBLIC_URL=/.Modules/AspNetCore.ClientApp.React/build
Check details at create react app user guide
YesSpaEnvCmdEnvironment=env_cmd_environment
Sets environment name for react apps using .env-cmdrc
Check details at env-cmd repository
If you run your host application in development mode YesSpa displays the internal stub page when you request an SPA path. This is because by default YesSpa does not build the SPA during development build (to speed up build and execution). In some cases you may want to see the actual application when running the host application. To do that perform the following steps:
- Make sure you build your SPA manually, for example:
npx ng build
The files in dist folder will be embedded into the SPA class library.
- Modify UseStubPage flag in Startup.Configure():
app.UseSpa(builder =>
{
builder.Options.UseStubPage = false;
builder.AddSpa(...);
...
});