Files
Alexander Abakumov 15e744da49 Initial commit: Complete Software Architecture course with 11 modules
- 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
2025-09-09 22:08:07 +03:00

5.4 KiB

Микрофронтенды

Навигация


Что такое микрофронтенды

Микрофронтенды — это архитектурный подход, где фронтенд приложения разбивается на независимые части.

Принципы микрофронтендов

1. Независимость

  • Независимая разработка
  • Независимое развертывание
  • Независимые команды

2. Технологическое разнообразие

  • Разные фреймворки
  • Разные библиотеки
  • Разные подходы

3. Единый пользовательский интерфейс

  • Общий дизайн
  • Общие компоненты
  • Общий пользовательский опыт

Архитектурные паттерны

1. Module Federation (Webpack 5)

// 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

// 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

<!-- 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

// 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

// 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

// 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

// 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>
  );
}

Преимущества микрофронтендов

Технические:

  • Независимая разработка
  • Технологическое разнообразие
  • Независимое развертывание
  • Масштабируемость команд

Организационные:

  • Независимые команды
  • Быстрая разработка
  • Специализация команд

Недостатки микрофронтендов

Сложность:

  • Сложность интеграции
  • Дублирование кода
  • Проблемы с производительностью
  • Сложность тестирования

Операционные:

  • Сложность развертывания
  • Проблемы с версионированием
  • Сложность мониторинга