Hone logo
Hone
Problems

Implementing a Basic Micro-Frontend Shell in Angular

Micro-frontends are an architectural style where a frontend application is composed of independently deployable smaller applications. This challenge focuses on building a simple Angular shell application that can load and display other micro-frontends dynamically. This is a crucial pattern for large, complex applications, enabling teams to work independently and deploy updates without impacting the entire system.

Problem Description

You are tasked with creating a basic Angular shell application that acts as a container for multiple micro-frontends. The shell will have a navigation component allowing users to select which micro-frontend to display. The micro-frontends themselves will be represented as separate Angular modules. The shell application should dynamically load and render the selected micro-frontend within a designated area.

What needs to be achieved:

  1. Shell Application: Create a new Angular application.
  2. Navigation Component: Implement a navigation component with buttons or links representing each micro-frontend.
  3. Micro-Frontend Modules: Create at least two separate Angular modules, each representing a micro-frontend. These modules should have a distinct component displaying some simple content (e.g., "Micro-Frontend A" and "Micro-Frontend B").
  4. Dynamic Loading: Implement logic in the shell application to dynamically load and display the selected micro-frontend module based on the user's navigation choice.
  5. Routing: Use Angular's routing mechanism to manage the display of different micro-frontends.

Key Requirements:

  • The shell application should be able to load micro-frontends on demand.
  • The micro-frontends should be isolated from each other (e.g., different CSS styles should not conflict).
  • The shell application should handle the loading and unloading of micro-frontends gracefully.
  • The navigation component should update the displayed micro-frontend when a user selects a different option.

Expected Behavior:

  • When the shell application loads, it should initially display a default micro-frontend (e.g., "Micro-Frontend A").
  • The navigation component should display options for each available micro-frontend.
  • Clicking on a navigation option should load and display the corresponding micro-frontend.
  • The previously displayed micro-frontend should be unloaded when a new one is loaded.

Edge Cases to Consider:

  • What happens if a micro-frontend fails to load? (Consider displaying an error message).
  • How can you handle different versions of micro-frontends? (This challenge doesn't require a full versioning system, but consider how you might approach it).
  • How would you manage shared dependencies between micro-frontends? (This challenge assumes minimal shared dependencies).

Examples

Example 1:

Input: Navigation options: "Micro-Frontend A", "Micro-Frontend B".  User clicks "Micro-Frontend B".
Output: The "Micro-Frontend B" component is displayed in the designated area of the shell application, replacing the previously displayed "Micro-Frontend A".
Explanation: The shell application dynamically loads the module for "Micro-Frontend B" and renders its component.

Example 2:

Input: Navigation options: "Micro-Frontend A", "Micro-Frontend B".  The "Micro-Frontend B" module fails to load due to a network error.
Output: An error message is displayed in the designated area of the shell application, indicating that "Micro-Frontend B" could not be loaded. "Micro-Frontend A" remains displayed.
Explanation: The shell application handles the error during the loading process and displays an appropriate message to the user.

Constraints

  • Technology Stack: Angular 16+ (or a recent stable version).
  • Module Size: Each micro-frontend module should be relatively small (e.g., under 50KB).
  • Loading Time: The loading time for a micro-frontend should be reasonably fast (e.g., under 2 seconds). While optimization isn't the primary focus, avoid excessively large or inefficient code.
  • Dependencies: Minimize shared dependencies between micro-frontends. Each micro-frontend should ideally be as self-contained as possible.

Notes

  • This challenge focuses on the shell application and the dynamic loading mechanism. You don't need to implement complex micro-frontend communication or state management.
  • Consider using Angular's RouterModule to manage navigation and routing between micro-frontends.
  • Think about how you would structure your project to keep the micro-frontends separate and maintainable. Using separate folders for each micro-frontend is a good starting point.
  • Error handling is important. Consider what happens if a micro-frontend fails to load.
  • This is a simplified example. Real-world micro-frontend architectures often involve more sophisticated techniques like Web Components or iframes.
Loading editor...
typescript