Micro-Frontend: Allow to have separate build/ releasable elements for lazy loaded modules

🚀 feature request

Relevant Package

@angular/cli

Description

With Micro-frontend being a hot topic those days, I have seen people taking the wrong approach with their angular projects. Thankfully, we have angular elements that allow us to create pure web-components, but unfortunately this have been misused to allow the micro frontend concept in an angular application. To allow smaller releasable packages, engineers started to create angular elements release them to a CDN site, and re-use them. This created a lot of fraction and challenges to integrate the different pieces. Not only that, but it’s also awkward, as you are creating vanilla javascript code from angular code to re-use it back again from an angular code. Other solutions was iframing, which also does not scale. Or releasing smaller libs to npm and re-using them in the code, which is not desired in the case of end to end integration and mon-repo large applications.

Describe the solution you’d like

If you have a solution in mind, please describe it.

Today, we are blessed by having the lazy loading approach which help us to generate separate chunks of the code and lazy load them as the user is visiting the relevant code. While this is great, there is no way to build those chunks separately and/or publish them to a standalone CDN/Server to be used later. I think to help teams avoid mistakes like listed above, it would be awesome if we can have angular CLI able to build these chunks separately, generate an artifact for it, which can be released individually. When this is accomplished, we can then have something like this:

const routes: Routes = [
  {
    path: 'items',
    loadChildren: () => import(env.prod? 'https://CDN-XYA/chunk1.js' : './items/items.module' ).then(m => m.ItemsModule)
  }
]; 

Describe alternatives you’ve considered

Yes, above but it’s not ideal. I think angular team need to get into the micro frontend business.

1 possible answer(s) on “Micro-Frontend: Allow to have separate build/ releasable elements for lazy loaded modules

  1. Thank you all for chiming in.

    Lazy-loading modules and microfrontends are very different and each solves different problems. Lazy-loaded modules are dependent on other parts of the application, are not self contained and cannot be built without building the entire application. It also means that changes in a lazy-loaded module might cause either one or more of the common/shared modules to be invalidated. A microfrontend on the other hand is dependency free and can be built and released on its own, in other words it’s isolated.

    There are multiple ways to achieve microfrontends, it mostly depends on your use-case.

    • Angular Elements
    • Single SPA https://single-spa.js.org/ which is a popular microfrontend router for React, Angular and Ember.
    • Module Federation
    • Iframes

    If you are using lazy-loading modules and want to release only what changed you can always check the diff and push to production the changed files. But again, lazy-loading and microfrontend are two different things and each solves different problems.

    Thankfully, we have angular elements that allow us to create pure web-components, but unfortunately this have been misused to allow the micro frontend concept in an angular application. To allow smaller releasable packages, engineers started to create angular elements release them to a CDN site, and re-use them.

    This is interesting, I don’t know that approach used here, but, I wonder if Angular Elements have been created at a low level instead of a higher level. For example, let’s say I have an item details page, in this case I would only create the top level component of the as an Elements and of it’s child components are still standard Angular components.

    Items microfrontend application

    - item-details-page     // Angular Element Component
    -- item-item-component  // Angular Component
    --- add-to-chart-button // Angular Component
    
    - item-list-page           // Angular Element Component
    -- item-grid-item-component // Angular Component
    --- item-item-component     // Angular Component
    ---- view-more-button       // Angular Component
    

    A lazy-loaded module in an application is not self contained and hence it breaks the microfrontend concept. Therefore,
    I am closing this issue as at this point I don’t see anything which is actionable by the tooling team.

    Module federation is being tracked here #17556

    Feel free to reply.