Blazor.WebAssembly.SingleSpa
Proof of concept around enabling the integration of Blazor WASM applications as micro frontends
targeting single-spa. This integration comprises two packages:
- Blazor.WebAssembly.SingleSpa – NuGet package that defines an alternate Blazor WebAssembly
start script that allows a WASM application to be used as a micro-frontend in a single-spa
web application.
- blazor-wasm-single-spa – NPM package that defines a
singleSpaBlazor
helper function for
defining the lifecycle hooks single-spa expects each micro-frontend to provide for bootstrapping,
mounting, and unmounting.
Applicable Versions
The Blazor.WebAssembly.SingleSpa NuGet package provides experimental support for projects targeting
the versions of .NET listed in the table below. Each entry in the table specifies the exact tagged
version of ASP.NET Core from which the assets were built.
For a given target framework version, the Blazor.WebAssembly.SingleSpa package may work for
previous minor/patch releases. However, no guarantees are given.
Usage
In general, installing the Blazor.WebAssembly.SingleSpa NuGet package in your Blazor WebAssembly
client project is sufficient for getting the modified Blazor startup script:
dotnet add package Blazor.WebAssembly.SingleSpa
The modified startup script (blazor.webassembly.js
) augments the window.Blazor
object created by
the Blazor runtime to expose additional APIs that make it possible to mount and unmount a Blazor
WASM application onto and from the DOM. However, to fully integrate and enable within a single-spa
web application, the Blazor WASM micro-frontend must also supply three lifecycle hooks single-spa
expects to import. These hooks are
bootstrap,
mount, and
unmount.
As a convenience, the blazor-wasm-single-spa NPM package exports a helper function for defining
these lifecycle hooks. The helper is modeled after many of the
official single-spa framework helpers available for many
popular JavaScript frameworks.
To use it, define a script inside your Blazor WASM application's wwwroot
folder, e.g.,
lifecycles.js
. Inside it, you could do the following to export the necessary lifecycle hooks:
import singleSpaBlazor from 'blazor-wasm-single-spa';
export const { bootstrap, mount, unmount } = singleSpaBlazor({
appTagName: 'my-blazor-app',
assetBaseUrl: new URL('https://mysite.com/apps/my-blazor-app/'),
navigationBaseUrl: new URL('https://mysite.com/blazor-app/'),
stylePaths: ['css/app.css', 'MyBlazorApp.Client.styles.css'],
additionalImportPaths: ['my-js-interop.js'],
beforeBlazorStart: (assetBaseUrl) => { },
afterBlazorRestore: (blazor) => { },
afterBlazorClear: (blazor) => { },
configureRuntime: (dotnet, props) => {
dotnet.withEnvironmentVariables({
MY_CONFIG_VALUE: 42,
});
},
injectRefreshScript: false,
appExtensions: [],
});
As part of this proof of concept, I have put together a simple web app built on single-spa that
incorporates both Lit-based and Blazor-based micro-frontends. See here:
blazing-lit-mfe-demo
Building Blazor.WebAssembly.SingleSpa from source
The following assumes you are working from the Blazor.WebAssembly.SingleSpa
directory.
This repository is structured around the following idea: for a given major version N
of ASP.NET
Core, a submodule named aspnetcore/N.x
is located at src/aspnetcore/N.x
. Each submodule is
configured to pull a version tag from the dotnet/aspnetcore
repository matching the specified
major version number, e.g., src/aspnetcore/8.x
pulls the commit of dotnet/aspnetcore
tagged with
v8.0.1
.
Within this project's patches
directory are a corresponding set of patches and scripts, one for
each major version of ASP.NET Core that has been tested. The Build-PatchedBlazorWasm.ps1
script in
each versioned directory will apply the patch located alongside it to the corresponding version of
the ASP.NET Core repository and build the necessary components to produce a set of patched Blazor
WebAssembly assets, such as the blazor.webassembly.js
startup script.
The final Blazor assets are then copied to the appropriate location within the
src/Blazor.WebAssembly.SingleSpa
project so that when the final NuGet is built the assets are in
the correct package location.
Installing prerequisites
Building this package requires .NET SDK 8+, Node.js 16.9+, Yarn 1, and PowerShell 7+.
.NET SDK 8+
Download from here.
Node.js
Installing Node can vary based on things like your operating system and your preferred workflow.
On Windows, I prefer to use nvm-windows, and on Mac
and Linux, I use nvm. Your mileage may vary. You just need to make
sure it is at least Node.js 16.9 or greater (LTS versions preferred).
Yarn 1
After Node is installed, install Yarn 1 globally:
npm install -g yarn
PowerShell
All the build and patch scripts are written in PowerShell for cross-platform support. Download it
from here.
Patching ASP.NET Core
To patch a version of ASP.NET Core's Blazor WASM startup script, run the
patches/<version>/Build-PatchedBlazorWasm.ps1
script.
:rocket: By default, the resulting script is minified. If you want to produce an unminified
version for reading and/or debugging purposes, pass the -DisableMinify
switch to the script.
Building Blazor.WebAssembly.SingleSpa
From the src/Blazor.WebAssembly.SingleSpa
directory, run dotnet pack -c Release
. This will
produce the final Blazor.WebAssembly.SingleSpa NuGet package.