single-spa-angular

repository·master·Indexed 42 days ago

https://github.com/single-spa/single-spa-angular

Helpers for building single-spa applications using Angular 2+. It provides the integration glue to allow multiple Angular microfrontends to coexist on a single page, featuring lifecycle management via singleSpaAngular(), zone-aware location handling with provideSingleSpa(), and support for Angular Elements and parcels.

Tokens
6.2K
Snippets
19
Records
27
Agent score
49%

What's inside single-spa-angular

  1. Check compatibility between single-spa-angular and Angular

    master

    This package uses a lock-step versioning strategy where the major version of single-spa-angular matches the major version of Angular. This ensures compatibility is easy to verify. Note that a major version bump in single-spa-angular is driven by Angular updates and does not necessarily imply breaking changes in the single-spa-angular API itself.

    single-spa-angularAngular
    21.x21.x
    20.x20.x
    19.x19.x
  2. How the library name is determined

    master

    The Webpack helper automatically attempts to determine a libraryName to ensure correct code-splitting and lazy loading. The resolution order is:

    1. Explicitly provided: Via options.customWebpackConfig.libraryName.
    2. Angular Workspace: It searches for angular.json, .angular.json, or workspace.json. In monorepos, it matches the main entry point against the project's architect.build.options.main configuration.
    3. Nx Workspace: It looks for nx.json and matches the project path against the current Webpack resolve.roots.
    4. Fallback: If no name can be determined, it defaults to 'angular_single_spa_project'.

    Warning: Using the default fallback name may cause issues with code-splitting or lazy loading. It is recommended to provide a libraryName explicitly if the automatic detection fails.

  3. Use Zoneless mode with single-spa-angular

    master

    If you want to run your Angular application in zoneless mode (where change detection is managed manually rather than via Zone.js), set the NgZone option to 'noop' in the singleSpaAngular configuration.

    When NgZone is set to 'noop':

    • The library will not attempt to wrap routing events in an Angular zone.
    • The requirement to provide provideSingleSpaPlatform() is skipped because the platform location override is not needed for zoneless applications.
    const bootstrap = singleSpaAngular({
      NgZone: 'noop' as any,
      bootstrapFunction: (props) => platformBrowser().bootstrapApplication(AppComponent, props),
      template: '<app-root />',
    });
  4. Configure the single-spa platform provider

    master

    To ensure proper URL synchronization and prevent infinite navigation loops between Angular and single-spa, you must provide the SingleSpaPlatformLocation class to the Angular platform. This is required for all applications, whether they use NgZone or are zoneless.

    Pass the result of provideSingleSpaPlatform() to platformBrowser() during your application bootstrapping process within the bootstrapFunction of your single-spa-angular configuration.

    const lifecycles = singleSpaAngular({
      bootstrapFunction: async () => {
        const platformRef = platformBrowser(provideSingleSpaPlatform());
        return bootstrapApplication(AppComponent, appConfig, { platformRef });
      },
      template: '<app-root />',
      NgZone: 'noop',
      Router,
      NavigationStart,
    });
  5. Automate project setup with the ng-add schematic

    master

    The ng-add schematic automates the integration of single-spa-angular into an existing Angular project. When executed via the Angular CLI, it performs the following sequence of operations:

    1. Adds Dependencies: Installs necessary npm packages.
    2. Creates Main Entry: Generates the required entry point for the single-spa application.
    3. Updates Configuration: Modifies the workspace configuration (e.g., angular.json) to support the single-spa lifecycle.
    4. Adds NPM Scripts: Injects relevant scripts into package.json.
    5. Routing Check: Issues a warning if Angular routing is already enabled, as this may require specific configuration for single-spa.

    To use this, you typically run the command through the Angular CLI in your project directory:

    ng add single-spa-angular
  6. Configure single-spa-angular in an Angular application

    master

    To integrate single-spa-angular into an Angular application using standalone APIs, include provideSingleSpa() in your ApplicationConfig providers array. This enables the necessary single-spa lifecycle integration for your Angular microfrontend.

    import { ApplicationConfig } from '@angular/core';
    import { provideSingleSpa } from 'single-spa-angular';
    
    export const appConfig: ApplicationConfig = {
      providers: [
        provideSingleSpa(),
        // ... other providers
      ],
    };
  7. Configure Angular Router for single-spa

    master

    When using Angular's router in a single-spa microfrontend, you must ensure that Angular's routing logic does not conflict with single-spa's orchestration of the browser URL.

    To prevent infinite routing loops (where single-spa triggers a navigation, Angular responds by updating the URL, which then triggers single-spa again), you must:

    1. Provide the Platform Location: You must call provideSingleSpaPlatform() when bootstrapping your application with platformBrowser() or platformBrowserDynamic(). This registers SingleSpaPlatformLocation, which overrides the default BrowserPlatformLocation to handle popstate events correctly.
    2. Pass Router and NavigationStart: In the singleSpaAngular configuration object, you must provide both the Router class and the NavigationStart event class.

    If Router is provided but provideSingleSpaPlatform() was not used, single-spa-angular will throw an error during the mount phase.

  8. Configure single-spa-angular using provideSingleSpa()

    master

    To integrate an Angular application into a single-spa microfrontend architecture, you must include provideSingleSpa() in your application's providers array within the ApplicationConfig. This enables the necessary single-spa lifecycle integration for the Angular application.

    import { provideSingleSpa } from 'single-spa-angular';
    import type { ApplicationConfig } from '@angular/core';
    
    export const appConfig: ApplicationConfig = {
      providers: [
        provideSingleSpa(),
        // ... other providers
      ],
    };
  9. Use provideSingleSpa() to enable single-spa location handling

    master

    In a single-spa micro-frontend environment, multiple Angular applications share the same browser platform. Standard Angular Location services may trigger popstate events inside the NgZone of the first bootstrapped application, causing other micro-frontends to miss route changes and skip change detection.

    To fix this, use provideSingleSpa() to replace the default Angular Location service with SingleSpaLocation. This implementation ensures that every popstate callback is wrapped in the current application's NgZone, guaranteeing that change detection is correctly triggered when routes change.

    Add provideSingleSpa() to your application's providers list, such as in bootstrapApplication or an NgModule.

    bootstrapApplication(AppComponent, {
      providers: [
        provideSingleSpa()
      ]
    });
  10. Set the application base href for microfrontends

    master

    When running an Angular application as a single-spa microfrontend, you often need to define a specific base href to ensure routing works correctly within the container. This is typically done by providing the APP_BASE_HREF token with the desired path (e.g., /shop).

    import { APP_BASE_HREF } from '@angular/common';
    import type { ApplicationConfig } from '@angular/core';
    
    export const appConfig: ApplicationConfig = {
      providers: [
        { provide: APP_BASE_HREF, useValue: '/shop' },
      ],
    };
  11. Configure Rollup for single-spa-angular builds

    master

    The createConfig function generates a Rollup configuration object tailored for building Angular microfrontends in the system (SystemJS) format. This configuration is designed to handle Angular's linker requirements and optimize for production.

    Configuration Parameters

    • input: The entry point for the build.
    • outputFile: The base name for the output file.
    • external: An array of dependencies that should be treated as external (not bundled).
    • prod: A boolean flag. When true, it enables minification via terser and applies specific Angular production optimizations.

    Output Format

    • Format: system (SystemJS).
    • File Path: Files are output to system/es2022/[outputFile].[min.]js. If prod is true, the filename includes .min..
    const config = createConfig({
      input: 'src/main.ts',
      outputFile: 'my-microfrontend',
      external: ['@angular/core'],
      prod: true
    });