Base solution for your next web application
Open Closed

Follow-up: Current Microfrontend Architecture Support for Angular and .NET Core in ASP.NET Zero #12700


User avatar
0
[email protected] created

Hi ASP.NET Zero Team,

It has been almost two years since this discussion, so I wanted to follow up and check whether there have been any updates regarding official support for Microfrontend Architecture in ASP.NET Zero with Angular and .NET Core.

Specifically, we would like to know:

  1. Is Microfrontend Architecture now officially supported in the latest ASP.NET Zero versions with Angular and .NET Core?
  2. Are there any recommended approaches or integrations, such as Webpack Module Federation, for implementing microfrontends?
  3. Can independently developed and deployed Angular microfrontends be integrated with the existing ASP.NET Zero backend and authentication/authorization mechanisms?
  4. Is there any official documentation, sample implementation, or recommended project structure available?
  5. Is there any roadmap for official support if it is still not available?

We are evaluating a scalable, modular architecture for a large enterprise application and would prefer to follow an approach that is compatible with ASP.NET Zero rather than introducing custom implementations that may create maintenance challenges during future upgrades.

Since this topic was raised two years ago, we would appreciate an updated response on the current capabilities and recommendations.

Thank you!

Markdown is supported
Copy & paste or drag & drop images (max 30 MB per image)

2 Answer(s)
  • User Avatar
    0
    oguzhanagir created
    Support Team

    Hi @sachin.kulkarni,

    Thanks for following up. ASP.NET Zero still has no official microfrontend support, so I will test a microfrontend setup for you on the latest version with Angular and .NET Core, including the integration with the existing backend and authentication/authorization. I will then share a document with you covering the results and our recommended approach.

    Best regards,

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    oguzhanagir created
    Support Team

    Hi @sachin.kulkarni,

    Thanks for following up. ASP.NET Zero still has no official microfrontend support, but we tried the setup on the v15.5 code base and it works, with some limits you should plan for. The main limit is that remotes have to stay aligned with the shell's Angular version.

    1. Is it officially supported?

    No. There is no built-in microfrontend support, and our releases are not tested against this setup.

    2. Which approach do we recommend?

    Use Native Federation rather than Webpack Module Federation. Zero's Angular app builds with the esbuild-based @angular/build:application builder, while Webpack Module Federation needs a webpack build. Native Federation keeps the same host and remote model on top of ES modules and import maps. It is a community project, not part of Angular or ASP.NET Zero.

    The adapter version must match your Angular version:

    • Zero v15.4 and later (Angular 22): @angular-architects/native-federation
    • Zero v15.2 and v15.3 (Angular 21): @angular-architects/native-federation-v4

    On v15.5 (Angular 22.2), we set up the Zero Angular project as the shell like this:

    pnpm add -D @angular-architects/native-federation@~22.2.0
    ng g @angular-architects/native-federation:init --project abp-zero-template --port 4200 --type dynamic-host
    

    The generated federation.config.mjs did not build on Zero, so we changed two things:

    • sharedMappings: []: otherwise the @app/*, @shared/* and @account/* paths are treated as shared libraries, and the build stops with Only barrel imports can be shared as a sharedMapping.
    • An explicit shared list: the generated config shares everything in package.json, and the build failed on the Node-only @angular-devkit/core package.
    import { withNativeFederation, share } from '@angular-architects/native-federation/config';
    
    const singleton = { singleton: true, strictVersion: true, requiredVersion: 'auto' };
    
    export default withNativeFederation({
        name: 'abp-zero-template',
        sharedMappings: [],
        shared: share({
            '@angular/core': singleton,
            '@angular/common': singleton,
            '@angular/router': singleton,
            '@angular/platform-browser': singleton,
            '@angular/forms': singleton,
            rxjs: singleton,
            tslib: singleton,
            'abp-ng2-module': singleton,
        }),
    });
    

    Keep the generated skip and features sections, and add any other library your remotes use to shared. A remote uses the same config with its own name and an exposes section.

    You then add the remote as a child of the existing app/main route, so AppRouteGuard applies as usual:

    {
        path: 'orders',
        loadComponent: () => loadRemoteModule('orders', './Component').then((m) => m.OrdersComponent),
        data: { permission: 'Pages.Orders' },
    },
    

    The top-level loadRemoteModule is marked as deprecated, so also check the dependency injection variant in the adapter docs.

    3. Can independently deployed remotes use the existing backend and auth?

    Yes, if the remote is loaded inside the Zero shell. We needed no backend changes, and in our test:

    • The remote's HttpClient call went through Zero's interceptor, with the bearer token and the Abp-TenantId header, and returned the correct user and tenant.
    • PermissionCheckerService, LocalizationService and TokenService from abp-ng2-module worked inside the remote.
    • A user without the route's permission was redirected, and the remote's component code was never downloaded.
    • We rebuilt and redeployed only the remote, and the new version appeared without rebuilding the shell.

    A fully separate Angular app outside the shell cannot rely on any of this. It would need its own login, for example through OpenIddict on Web.Host, and its origin added to App:CorsOrigins. We did not test that scenario.

    What to plan for

    • Angular versions: you can deploy remotes independently, but you cannot upgrade Angular independently.
      • With the generated requiredVersion: 'auto', the versions must match exactly. Remotes on 22.2.0, 22.1.8 and 21.2.0 against a 22.2.3 shell each loaded their own @angular/core, and the route failed with NG0203. The rest of the application kept working.
      • With requiredVersion: '^22.0.0' and strictVersion: false on the Angular packages, the 22.2.0 and 22.1.8 remotes reused the shell's Angular and rendered correctly.
      • A 21.2.0 remote also rendered with a wider range, but our component was trivial, so we would not rely on that across major versions.
      • Zero moved from Angular 21 to 22 between v15.3 and v15.4, so plan to rebuild every remote when you upgrade Zero. A remote that must stay on another Angular version needs a stronger boundary, such as an iframe or a web component (the adapter's --webcomponent option, which we did not test).
    • CORS on the remote's host: the browser loads remoteEntry.json and the module files across origins, so the remote's static host must send Access-Control-Allow-Origin. Without it, the route failed. App:CorsOrigins needs no change for this, because API calls come from the shell's origin.
    • No access to shell code: @shared and @app are path aliases into the shell's source, not packages. A remote cannot import AppComponentBase, AppSessionService or the generated service-proxies.ts, so give each remote its own NSwag configuration. If you extract shared code into a library, keep it small, because moving template files makes future Zero merges harder.
    • Runtime dependency on the shell: the abp global, the session and the Metronic styles all come from the shell. The shell also runs without zone.js, so remotes must be zoneless-compatible. It is simplest to develop remotes against a locally running shell.
    • Changes that still touch the shell or backend: a new remote needs a route and a menu entry in AppNavigationService, unless you build those dynamically. Permissions and localization texts live on the backend, so changing them still means deploying Web.Host.
    • Security: a remote runs with the signed-in user's full access, and the Abp.AuthToken cookie is readable from JavaScript. Only load remotes you trust, control who can change the manifest, and keep [AbpAuthorize] on your application services as the real enforcement.
    • Zero upgrades: the schematic moves your main.ts content to bootstrap.ts, so upstream main.ts changes must be merged there. The adapter version also has to move with Angular.

    4. Is there official documentation or a sample?

    No, there is no official documentation, sample or project structure. We would keep the Zero Angular app as the shell, as close to the template as possible, and put each remote in its own workspace with its own federation and NSwag configuration. The adapter docs and the Native Federation playground are good starting points.

    5. Is there a roadmap?

    We have no committed timeline for official support.

    What we tested

    This was a small proof of concept, not a production validation: production builds on Angular 22.2 with one remote exposing one standalone component, run in Chromium. We did not test ng serve, multiple remotes, remotes with their own child routes, UI libraries such as ng-zorro inside a remote, or other Zero versions. The two config changes above may differ on other adapter versions.

    Before committing to this, it is worth checking that you really need it. Microfrontends pay off when separate teams need separate release cycles. If that is not your situation, the template's lazy-loaded routes with one folder per module give you a modular structure without any of the limits above.

    If you do go ahead, it would help to know how many teams and remotes you expect, and whether any of them must stay on a different Angular version. We can then give you more specific advice.

    Best regards,

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)