- Added comprehensive course structure with 11 modules - Included theoretical content, practical examples, and tasks - Multi-language code examples (Java, Rust, Node.js, Python) - Detailed analysis of architectural approaches and trade-offs - Complete caching strategies documentation - Architecture examples from real-world systems (Twitter, Netflix, Uber) - Structured navigation and learning path - Ready for educational use
241 lines
5.4 KiB
Markdown
241 lines
5.4 KiB
Markdown
# Микрофронтенды
|
|
|
|
## Навигация
|
|
- [🏠 Главная страница курса](../../../README.md)
|
|
- [📚 Модуль 2](../README.md)
|
|
|
|
---
|
|
|
|
## Что такое микрофронтенды
|
|
|
|
**Микрофронтенды** — это архитектурный подход, где фронтенд приложения разбивается на независимые части.
|
|
|
|
## Принципы микрофронтендов
|
|
|
|
### 1. Независимость
|
|
- Независимая разработка
|
|
- Независимое развертывание
|
|
- Независимые команды
|
|
|
|
### 2. Технологическое разнообразие
|
|
- Разные фреймворки
|
|
- Разные библиотеки
|
|
- Разные подходы
|
|
|
|
### 3. Единый пользовательский интерфейс
|
|
- Общий дизайн
|
|
- Общие компоненты
|
|
- Общий пользовательский опыт
|
|
|
|
## Архитектурные паттерны
|
|
|
|
### 1. Module Federation (Webpack 5)
|
|
```javascript
|
|
// shell/ModuleFederationPlugin.js
|
|
new ModuleFederationPlugin({
|
|
name: 'shell',
|
|
remotes: {
|
|
'product': 'product@http://localhost:3001/remoteEntry.js',
|
|
'cart': 'cart@http://localhost:3002/remoteEntry.js',
|
|
},
|
|
});
|
|
|
|
// product/webpack.config.js
|
|
new ModuleFederationPlugin({
|
|
name: 'product',
|
|
filename: 'remoteEntry.js',
|
|
exposes: {
|
|
'./ProductList': './src/ProductList',
|
|
},
|
|
});
|
|
```
|
|
|
|
### 2. Single-SPA
|
|
```javascript
|
|
// main.js
|
|
import { registerApplication, start } from 'single-spa';
|
|
|
|
registerApplication({
|
|
name: 'product',
|
|
app: () => System.import('product'),
|
|
activeWhen: ['/products'],
|
|
});
|
|
|
|
registerApplication({
|
|
name: 'cart',
|
|
app: () => System.import('cart'),
|
|
activeWhen: ['/cart'],
|
|
});
|
|
|
|
start();
|
|
```
|
|
|
|
### 3. iframe-based
|
|
```html
|
|
<!-- shell/index.html -->
|
|
<div id="product-microfrontend">
|
|
<iframe src="http://localhost:3001/products"
|
|
width="100%"
|
|
height="600px">
|
|
</iframe>
|
|
</div>
|
|
|
|
<div id="cart-microfrontend">
|
|
<iframe src="http://localhost:3002/cart"
|
|
width="100%"
|
|
height="400px">
|
|
</iframe>
|
|
</div>
|
|
```
|
|
|
|
## Управление состоянием
|
|
|
|
### 1. Shared State
|
|
```javascript
|
|
// shared-state/store.js
|
|
class SharedStore {
|
|
constructor() {
|
|
this.state = {};
|
|
this.subscribers = [];
|
|
}
|
|
|
|
setState(newState) {
|
|
this.state = { ...this.state, ...newState };
|
|
this.notifySubscribers();
|
|
}
|
|
|
|
subscribe(callback) {
|
|
this.subscribers.push(callback);
|
|
}
|
|
|
|
notifySubscribers() {
|
|
this.subscribers.forEach(callback => callback(this.state));
|
|
}
|
|
}
|
|
|
|
export const sharedStore = new SharedStore();
|
|
```
|
|
|
|
### 2. Event Bus
|
|
```javascript
|
|
// shared/eventBus.js
|
|
class EventBus {
|
|
constructor() {
|
|
this.events = {};
|
|
}
|
|
|
|
on(event, callback) {
|
|
if (!this.events[event]) {
|
|
this.events[event] = [];
|
|
}
|
|
this.events[event].push(callback);
|
|
}
|
|
|
|
emit(event, data) {
|
|
if (this.events[event]) {
|
|
this.events[event].forEach(callback => callback(data));
|
|
}
|
|
}
|
|
}
|
|
|
|
export const eventBus = new EventBus();
|
|
```
|
|
|
|
## Коммуникация между микрофронтендами
|
|
|
|
### 1. Props/Events
|
|
```javascript
|
|
// shell/App.js
|
|
import ProductMicrofrontend from 'product/ProductList';
|
|
import CartMicrofrontend from 'cart/CartList';
|
|
|
|
function App() {
|
|
const [cartItems, setCartItems] = useState([]);
|
|
|
|
const handleAddToCart = (product) => {
|
|
setCartItems([...cartItems, product]);
|
|
};
|
|
|
|
return (
|
|
<div>
|
|
<ProductMicrofrontend onAddToCart={handleAddToCart} />
|
|
<CartMicrofrontend items={cartItems} />
|
|
</div>
|
|
);
|
|
}
|
|
```
|
|
|
|
### 2. Custom Events
|
|
```javascript
|
|
// product/ProductList.js
|
|
function ProductList() {
|
|
const handleAddToCart = (product) => {
|
|
// отправляем событие
|
|
window.dispatchEvent(new CustomEvent('addToCart', {
|
|
detail: product
|
|
}));
|
|
};
|
|
|
|
return (
|
|
<div>
|
|
{products.map(product => (
|
|
<button onClick={() => handleAddToCart(product)}>
|
|
Add to Cart
|
|
</button>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// cart/CartList.js
|
|
function CartList() {
|
|
const [items, setItems] = useState([]);
|
|
|
|
useEffect(() => {
|
|
const handleAddToCart = (event) => {
|
|
setItems([...items, event.detail]);
|
|
};
|
|
|
|
window.addEventListener('addToCart', handleAddToCart);
|
|
|
|
return () => {
|
|
window.removeEventListener('addToCart', handleAddToCart);
|
|
};
|
|
}, [items]);
|
|
|
|
return (
|
|
<div>
|
|
{items.map(item => (
|
|
<div key={item.id}>{item.name}</div>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|
|
```
|
|
|
|
## Преимущества микрофронтендов
|
|
|
|
### Технические:
|
|
- Независимая разработка
|
|
- Технологическое разнообразие
|
|
- Независимое развертывание
|
|
- Масштабируемость команд
|
|
|
|
### Организационные:
|
|
- Независимые команды
|
|
- Быстрая разработка
|
|
- Специализация команд
|
|
|
|
## Недостатки микрофронтендов
|
|
|
|
### Сложность:
|
|
- Сложность интеграции
|
|
- Дублирование кода
|
|
- Проблемы с производительностью
|
|
- Сложность тестирования
|
|
|
|
### Операционные:
|
|
- Сложность развертывания
|
|
- Проблемы с версионированием
|
|
- Сложность мониторинга
|