Building a Basic Micro-Frontend System with React and TypeScript
Micro-frontends are an architectural style where a frontend application is composed of independently deployable smaller applications. This challenge asks you to build a simplified micro-frontend system using React and TypeScript, demonstrating how multiple React applications can coexist and communicate within a single shell application. This is useful for large, complex projects where teams can work independently on different parts of the UI.
Problem Description
You need to create a basic micro-frontend system consisting of a shell application and two micro-frontends: a "Product List" and a "Cart". The shell application will load and render these micro-frontends dynamically. Each micro-frontend should be a separate React application bundled independently. The shell application will use a simple mechanism (e.g., a prop passed down) to communicate a shared state (a user ID) to each micro-frontend.
What needs to be achieved:
- Shell Application: Create a React application that acts as the container for the micro-frontends. This application should:
- Dynamically load and render the "Product List" and "Cart" micro-frontends.
- Pass a
userIdprop (initially set to123) to both micro-frontends.
- Product List Micro-Frontend: Create a React application that displays a list of products. This application should:
- Receive the
userIdprop. - Display a simple list of products (e.g., using hardcoded data).
- Display the
userIdin a designated area of the component.
- Receive the
- Cart Micro-Frontend: Create a React application that displays a shopping cart. This application should:
- Receive the
userIdprop. - Display a simple cart (e.g., using hardcoded data).
- Display the
userIdin a designated area of the component.
- Receive the
Key Requirements:
- Independent Bundling: Each micro-frontend (Product List and Cart) must be bundled as a separate JavaScript file (e.g., using Webpack or Parcel).
- Dynamic Loading: The shell application must dynamically load these bundled JavaScript files. You can use
import()for dynamic imports. - Prop Passing: The shell application must pass the
userIdprop to each micro-frontend. - TypeScript: All code must be written in TypeScript.
- Clear Separation: The code should clearly demonstrate the separation of concerns between the shell and the micro-frontends.
Expected Behavior:
When the shell application loads, it should render both the "Product List" and "Cart" micro-frontends. Each micro-frontend should display its respective content and the userId (123) in a visible location.
Edge Cases to Consider:
- Loading Errors: Consider how the shell application should handle errors if a micro-frontend fails to load. (Basic error handling is sufficient for this challenge - a simple console error message is acceptable).
- Micro-frontend Updates: While not required for this challenge, think about how you might update a micro-frontend without reloading the entire shell application.
Examples
Example 1:
Input: Shell application loads with userId = 123
Output: Shell application renders Product List and Cart micro-frontends. Product List displays a list of products and "userId: 123". Cart displays a shopping cart and "userId: 123".
Explanation: The shell application successfully loads and renders both micro-frontends, passing the userId prop as expected.
Example 2:
Input: Product List micro-frontend fails to load due to a bundling error.
Output: Shell application displays a console error message indicating the Product List failed to load. The Cart micro-frontend still renders correctly.
Explanation: The shell application handles the loading error gracefully and continues to render the remaining micro-frontends.
Constraints
- Bundling: Use a module bundler (Webpack, Parcel, Rollup) to create separate bundles for each micro-frontend. You don't need to configure complex bundling options; basic configuration is sufficient.
- Dynamic Imports: Use
import()for dynamic loading of micro-frontend bundles. - User ID: The initial
userIdvalue must be123. - Data: You can use hardcoded data for the product list and cart contents.
- Error Handling: Basic console error logging is sufficient for error handling.
- Time Limit: Aim to complete the challenge within 2-3 hours.
Notes
- This challenge focuses on the core concepts of micro-frontends: independent bundling, dynamic loading, and prop passing.
- Consider using a simple React component as the entry point for each micro-frontend.
- Think about how you might structure your project directory to clearly separate the shell application and the micro-frontends.
- The goal is to demonstrate a working, albeit basic, micro-frontend system. Advanced features like routing, communication between micro-frontends, or complex state management are not required for this challenge.
- Focus on clean, readable, and well-documented code.