Introduction
Micro-frontends extend the microservices concept to frontend development, allowing independent teams to work on different parts of an application autonomously. This architecture pattern solves scalability challenges in large organizations.
Module Federation with Webpack 5
// webpack.config.js (Host App)
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'host',
remotes: {
productApp: 'productApp@http://localhost:3001/remoteEntry.js',
cartApp: 'cartApp@http://localhost:3002/remoteEntry.js',
},
shared: {
react: { singleton: true },
'react-dom': { singleton: true },
},
}),
],
};
// webpack.config.js (Product Micro-frontend)
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'productApp',
filename: 'remoteEntry.js',
exposes: {
'./ProductList': './src/components/ProductList',
'./ProductDetail': './src/components/ProductDetail',
},
shared: {
react: { singleton: true },
'react-dom': { singleton: true },
},
}),
],
};
Loading Remote Components
// Host app
import React, { lazy, Suspense } from 'react';
const ProductList = lazy(() => import('productApp/ProductList'));
const Cart = lazy(() => import('cartApp/Cart'));
function App() {
return (
<div>
<Suspense fallback={<Loading />}>
<ProductList />
<Cart />
</Suspense>
</div>
);
}
Team Organization
// Teams and ownership
teams = {
checkout: {
owns: ['cart', 'payment', 'order-confirmation'],
tech: ['React', 'Node.js'],
deployment: 'Independent'
},
catalog: {
owns: ['product-list', 'product-detail', 'search'],
tech: ['Vue', 'Express'],
deployment: 'Independent'
}
}