Mikro Önyüz Mimarisi: Önyüz Geliştirmeyi Ölçeklendirme
Mikro önyüz mimarisine dair pratik bir rehber: Modül Federasyonu, iframe entegrasyonu, single-spa, iletişim kalıpları, yönlendirme, dağıtım ve mimariden ne zaman kaçınılması gerektiği.
Mikro önyüzler, mikroservis konseptini önyüz katmanına taşır. Tek bir monolitik uygulama yerine önyüz, daha küçük ve bağımsız uygulamalara ayrıştırılır; her biri ayrı ayrı geliştirilir, test edilir ve dağıtılır. Her bir mikro önyüz, belirli bir iş alanını sahiplenir ve farklı ekipler tarafından, farklı teknolojilerle ve farklı sürüm takvimleriyle geliştirilebilir.
Bu mimari, arka uçta mikroservislerin benimsenmesini tetikleyen aynı baskılardan doğdu. Web uygulamaları karmaşıklaştıkça, monolitik önyüzlerin bakımı zorlaştı, yapım süreleri uzadı ve dağıtım riskli hale geldi. Kod tabanındaki tek bir değişiklik, tüm uygulamanın yeniden derlenmesini ve dağıtılmasını gerektiriyor, ekipleri yavaşlatıyor ve farklı hızlarda ilerlemek isteyen gruplar arasında sürtüşme yaratıyordu.
Mikro Önyüz Nedir?
Mikro önyüz mimarisi, bir web uygulamasını özellik dilimlerine ayırır ve her dilim bağımsız bir ekibin sahipliğine verilir. Ekip, kendi diliminin her katmanından sorumludur: arayüz bileşenleri, iş mantığı, veri çekme ve arka uç entegrasyonu. Kullanıcı tek ve uyumlu bir uygulama görür ancak perde arkasında, aynı tarayıcı penceresinde çalışan birden fazla küçük uygulamadan oluşan bir yapı vardır.
Bu ayrıştırma, Eric Evans tarafından popülerleştirilen domain-driven design prensiplerini yansıtır. Her mikro önyüz, sınırlı bir bağlama — belirli bir iş yeteneğinin etrafındaki mantıksal bir sınıra — karşılık gelir. Ödeme deneyimi, ürün kataloğu, kullanıcı profili ve arama özelliği, her biri ayrı ekiplerin sahiplendiği ayrı mikro önyüzler olabilir.
Mikro önyüzlerle kodu modüllere ayırmak arasındaki temel fark, mikro önyüzlerin derleme ve dağıtım zamanında bağımsız olmasıdır. Her mikro önyüzün kendi derleme hattı, kendi deposu, kendi testleri ve kendi dağıtım takvimi vardır. Bu bağımsızlık, mimariye avantajlarını kazandıran ve zorluklarını yaratan şeydir.
Mikro önyüz, bir bileşen kütüphanesi veya paylaşılan araçlar seti değildir. Çalışma zamanında daha büyük bir uygulamanın içine yerleştirilen bağımsız bir uygulamadır. Bu ayrım, mimarinin hem gücünü hem de maliyetini anlamak açısından kritiktir.
Webpack 5 ile Modül Federasyonu
Modül Federasyonu, React ve Angular ekosistemlerinde mikro önyüzler için en popüler yaklaşımdır. Webpack 5 ile tanıtılan bu özellik, bir JavaScript uygulamasının çalışma zamanında başka bir uygulamadan kod dinamik olarak yüklemesine olanak tanır. Yüklenen kod, ana uygulamanın bağlamında çalışır ve React veya Vue gibi kütüphanelerin tekrarlanmasını önlemek için bağımlılıkları paylaşır.
Modül Federasyonu, uzak bir uygulamadaki belirli modülleri dışa aktararak ve bunları ana uygulamaya içe aktararak çalışır. Uzak uygulama, tüketime sunulan modülleri bildirir; ana uygulama ise bu modülleri yerel import'lar gibi referans alır. Webpack, derleme zamanında asenkron yüklemeyi, bağımlılık tekrarını önlemeyi ve sürüm çözümlemesini halleder.
Paylaşılan bağımlılık mekanizması, Modül Federasyonu'nun en önemli özelliğidir. Ana uygulama ve uzak uygulama aynı kütüphaneyi kullandığında, Webpack tarayıcıya yalnızca bir kopyanın yüklenmesini sağlar. Bu, React, Lodash veya diğer büyük kütüphanelerin birden fazla kopyasının yüklenmesinden kaynaklanacak performans düşüşünü önler. Singleton deseni ayrıca, paylaşılan durumun — bir Redux store veya React context gibi — mikro önyüzler arasında gerçekten paylaşılmasını sağlar.
// webpack.config.js — Bir modülü dışa aktaran uzak uygulama
const { ModuleFederationPlugin } = require("webpack").container;
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: "checkout",
filename: "remoteEntry.js",
exposes: {
"./CheckoutApp": "./src/bootstrap",
},
shared: {
react: { singleton: true, requiredVersion: "^18.0.0" },
"react-dom": { singleton: true, requiredVersion: "^18.0.0" },
},
}),
],
};
// webpack.config.js — Uzak uygulamayı tüketen ana uygulama
const { ModuleFederationPlugin } = require("webpack").container;
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: "shell",
remotes: {
checkout: "checkout@http://localhost:3001/remoteEntry.js",
},
shared: {
react: { singleton: true, requiredVersion: "^18.0.0" },
"react-dom": { singleton: true, requiredVersion: "^18.0.0" },
},
}),
],
};
// Ana uygulamada uzak modülün tembel yüklenmesi
const CheckoutApp = React.lazy(() => import("checkout/CheckoutApp"));
function Shell() {
return (
<Suspense fallback={<Spinner />}>
<CheckoutApp />
</Suspense>
);
}Ana uygulama, kullanıcı ödeme mikro önyüzünü gerektiren bir rotaya gittiğinde uzak giriş dosyasını yükler. Uzak giriş dosyası, Webpack'in otomatik olarak oluşturduğu küçük bir JavaScript dosyasıdır. Tüm dışa aktarılan modüllerin ve konumlarının bir manifestosunu içerir. Ana uygulama belirli bir modülü istediğinde, Webpack ilgili parçayı indirir ve paylaşılan bağımlılık bağlamında çalıştırır.
Modül Federasyonu ile ilgili önemli bir husus, ana ve uzak uygulamanın paylaşılan bağımlılık sürümleri üzerinde anlaşması gerektiğidir. Uzak uygulama React 18.2 gerektiriyor ancak ana uygulamada yalnızca React 18.0 varsa, sürümler uyumlu olmadığı sürece singleton paylaşımı başarısız olur. Paylaşılan yapılandırmadaki requiredVersion alanı, semantik sürüm aralıkları kullanarak size esneklik sağlarken kırıcı değişikliklere karşı koruma sunar.
iframe Tabanlı Entegrasyon
Modül Federasyonu ve diğer modern entegrasyon tekniklerinden önce, iframe'ler orijinal mikro önyüz yaklaşımıydı. Bir iframe, ana sayfanın içine tamamen bağımsız bir HTML belgesi gömer. Gömülü belgenin kendi JavaScript bağlamı, kendi CSS kapsamı ve kendi DOM ağacı vardır. Bu yalıtım, yaklaşımın hem gücü hem de zayıflığıdır.
iframe yaklaşımı, tüm mikro önyüz teknikleri arasında en güçlü yalıtım garantilerini sağlar. Her iframe'in kendi belgesi olduğu için CSS çakışması riski yoktur. Her iframe'in kendi global kapsamı olduğu için JavaScript çakışması riski yoktur. DOM ağaçları tamamen ayrı olduğu için bir mikro önyüzün diğerinin durumunu yanlışlıkla değiştirme riski yoktur. Bir mikro önyüzdeki bellek sızıntısı diğerini çökertemez.
Bu yalıtım garantilerinin bir bedeli vardır. iframe'ler ağırdır. Her iframe, tüm CSS ve JavaScript kaynakları dahil olmak üzere eksiksiz bir HTML belgesi yükler. Tarayıcı, her iframe'i ayrı bir gezinme bağlamı olarak ele alır; bu da ek bellek kullanımı, ek ağ istekleri ve ek işleme anlamına gelir. On mikro önyüzü iframe içine gömerseniz, kullanıcının tarayıcısı etkin bir şekilde on bir sayfa yükler.
Bir iframe ile ana sayfa arasındaki iletişim, asenkron olan ve yalnızca serileştirilebilir verilerle sınırlı olan postMessage API'sini gerektirir. Fonksiyonları, sınıf örneklerini veya DOM referanslarını iframe sınırı boyunca iletmek imkansızdır. Bu, iframe'leri sıkı entegrasyon gerektiren mikro önyüzler için uygunsuz hale getirir — örneğin, ana sayfa sepet durumuna erişmesi gereken bir ödeme formu.
Erişilebilirlik başka bir endişe kaynağıdır. Ekran okuyucular ve diğer yardımcı teknolojiler, iç içe geçmiş gezinme bağlamlarıyla genellikle zorlanır. iframe sınırları arasında klavye navigasyonu tutarsız olabilir. Tarayıcının sayfa içi arama özelliği iframe sınırları arasında arama yapmaz ve tarayıcı geçmişi her iframe navigasyonunu ayrı bir oturum olarak ele alır.
Iframe'ler, yalıtımın kritik olduğu ve entegrasyonun minimal olduğu üçüncü taraf içeriklerini gömmek için en uygunudur. Mikro önyüzlerin durum paylaşması, navigasyonu koordine etmesi veya birleşik bir görsel yüzey olarak işlenmesi gereken uyumlu bir uygulama deneyimi oluşturmak için kötü bir seçimdir.
Single-SPA ve Diğer Orkestrasyon Çerçeveleri
Single-spa, birden fazla mikro önyüzü tek bir sayfada orkestre etmek için kullanılan bir JavaScript çerçevesidir. Her mikro önyüzün yaşam döngüsünü yönetir — kullanıcı gerektiren bir rotaya gittiğinde bağlama, kullanıcı ayrıldığında çözme ve hızlı yeniden bağlama için kullanılmayan mikro önyüzleri bellekte tutma. Single-spa, çerçeve bağımsızdır ve React, Angular, Vue, Svelte ve vanilla JavaScript'i destekler.
Single-spa'daki her mikro önyüz, bir dizi yaşam döngüsü fonksiyonuyla (bootstrap, mount, unmount ve isteğe bağlı update) kendini bir uygulama olarak kaydeder. Single-spa kök bileşeni yönlendirmeyi kontrol eder ve URL kalıplarına göre hangi uygulamaların aktif olduğuna karar verir. URL, kayıtlı bir uygulamanın aktivite fonksiyonuyla eşleştiğinde, single-spa bu uygulamayı bağlar ve artık aktif olmayan uygulamaları çözer.
Single-spa, mikro önyüzlerdeki en zor sorunlardan birini çözer: çerçeve uyumlaştırması. İki mikro önyüz, aynı çerçevenin farklı sürümleriyle veya tamamen farklı çerçevelerle oluşturulduğunda, single-spa bunların çakışma olmadan aynı sayfada bir arada bulunmasını sağlar. Bu, çerçevenin yaşam döngüsü hook'larını yamalayarak ve her uygulamanın global durumunu yalıtarak başarılır.
Diğer orkestrasyon yaklaşımları arasında, mikro önyüzlerin bir besleme servisinden modüller olarak yüklendiği eklenti tabanlı bir model kullanan Piral ve sunucu tarafı birleştirmeye odaklanan Open Components bulunur. Ayrıca web bileşen yaklaşımı da vardır; burada her mikro önyüz özel bir elemente sarılır ve tarayıcının Custom Elements API'si ile kaydedilir. Web bileşenleri, HTML, CSS ve JavaScript için yerel kapsamlama sağlar ve HTML şablonlarında bildirimsel olarak birleştirilebilir.
Orkestrasyon stratejisi seçimi, teknoloji yığınınıza, ekip yapınıza ve performans gereksinimlerinize bağlıdır. Modül Federasyonu, halihazırda Webpack kullanan ekipler için en iyi seçimdir. Single-spa, farklı mikro önyüzlerin farklı çerçeveler kullandığı çok dilli mimariler için uygundur. Web bileşenleri, çerçeve bağımsız sınırlar uygulamak isteyen kuruluşlar için iyi çalışır. Iframe'ler yalnızca üçüncü taraf gömme senaryoları için uygundur.
Paylaşılan Bileşen Kütüphaneleri ve Tasarım Sistemleri
Mikro önyüzlerle ilgili yaygın bir endişe, görsel tutarsızlıktır. Her ekip kendi arayüzünü bağımsız olarak oluşturursa, kullanıcı uygulamada gezinirken farklı buton stilleri, farklı tipografi ve farklı düzen desenleri görebilir. Çözüm, tüm mikro önyüzlerin tükettiği paylaşılan bir bileşen kütüphanesi veya tasarım sistemidir.
Paylaşılan kütüphane tipik olarak butonlar, girdi alanları, modal pencereler ve gezinme öğeleri gibi sunum bileşenlerini içerir. Bu bileşenler tamamen görseldir ve herhangi bir iş mantığı içermez. Stil varyasyonları, etiketler ve olay işleyicileri için prop'lar alırlar ancak veri çekmez, durum yönetmez veya alana özgü herhangi bir davranış uygulamazlar. Bu ayrım, kütüphanenin istikrarlı kalmasını ve ekip hızı için darboğaz haline gelmemesini sağlar.
Paylaşılan kütüphaneyi sürümlemek dikkatli planlama gerektirir. Kütüphane bir npm paketi olarak yayınlanırsa, her mikro önyüz belirli bir sürüme sabitlenir ve kendi takvimine göre güncelleme yapar. Bu, ekiplere özerklik verir ancak farklı mikro önyüzlerin kütüphanenin farklı sürümlerini kullanması nedeniyle aynı bileşeni farklı şekilde işlemesine yol açacak sürüm kaymasına neden olabilir. Kütüphane için bir görsel regresyon test paketi, bu tutarsızlıkların üretime ulaşmadan yakalanmasına yardımcı olur.
Alternatif bir yaklaşım, tasarım sistemini çalışma zamanı bağımlılığı olarak sunmaktır. Paylaşılan kütüphane, bağımsız bir uygulama olarak dağıtılır ve her mikro önyüz tarafından çalışma zamanında yüklenir. Bu, her mikro önyüzün her bileşenin her zaman en son sürümünü kullanmasını sağlayarak sürüm kaymasını ortadan kaldırır. Ödünleşim, tasarım sistemini güncellemenin artık bir dağıtım gerektirmesi ve herhangi bir kırıcı değişikliğin tüm mikro önyüzleri aynı anda etkilemesidir.
En alt düzey ortak payda olarak tasarım token'ları
Tasarım token'ları — renkler, boşluklar, tipografi ve gölgeler için adlandırılmış değerler — tam bir bileşen kütüphanesine daha hafif bir alternatif sunar. Her mikro önyüz kendi bileşenlerini uygular ancak aynı tasarım token'ları kümesine referans verir. Bu, ekiplere uygulama esnekliği sağlarken görsel tutarlılığı korur. Token'lar, geçersiz kılınması kolay olan ve tüketmek için herhangi bir derleme aracı gerektirmeyen CSS özel nitelikleri olarak dağıtılabilir.
Mikro Önyüzler Arasında İletişim
Mikro önyüzlerin birbirleriyle iletişim kurması gerekir. Ödeme mikro önyüzü, kullanıcının katalog mikro önyüzünde sepete ne eklediğini bilmelidir. Başlık mikro önyüzü, bildirim mikro önyüzü yeni bir bildirim aldığında bildirim rozetini güncellemelidir. Giriş mikro önyüzü, kullanıcı giriş yaptığında veya çıkış yaptığında diğer tüm mikro önyüzleri bilgilendirmelidir.
En basit iletişim mekanizması, paylaşılan bir olay veri yoludur. Her mikro önyüz, global bir kanala olaylar yayınlayabilir ve diğer mikro önyüzlerden gelen olaylara abone olabilir. Olay veri yolu tipik olarak window nesnesine eklenen veya ana kabuk tarafından enjekte edilen özel bir olam yayıcı olarak uygulanır. Olaylar bir tür ve yük taşır; aboneler olayları türe göre filtreler.
// Paylaşılan olay veri yolu — kabuk uygulama
// Her mikro önyüz bu veri yolunu başlatma sırasında alır.
type BusEvent = {
type: string;
payload: unknown;
};
type Listener = (event: BusEvent) => void;
class EventBus {
private listeners: Map<string, Listener[]> = new Map();
on(type: string, listener: Listener): () => void {
if (!this.listeners.has(type)) {
this.listeners.set(type, []);
}
this.listeners.get(type)!.push(listener);
return () => this.off(type, listener);
}
off(type: string, listener: Listener): void {
const listeners = this.listeners.get(type);
if (listeners) {
this.listeners.set(
type,
listeners.filter((l) => l !== listener)
);
}
}
emit(type: string, payload: unknown): void {
this.listeners.get(type)?.forEach((listener) => {
listener({ type, payload });
});
}
}
// Bir mikro önyüzde kullanım
export function init(bus: EventBus) {
bus.on("item:added-to-cart", (event) => {
updateCartBadge(event.payload.quantity);
});
bus.emit("user:logged-in", { userId: "abc-123", name: "Jane" });
}Daha karmaşık iletişim ihtiyaçları için, paylaşılan bir durum deposu genellikle olay veri yolundan daha iyidir. Kabuk uygulamada yaşayan paylaşılan bir Redux store veya Zustand store, her mikro önyüze enjekte edilebilir. Her mikro önyüz, alanlar arası durum için paylaşılan depodan okur ve alana özgü durum için kendi yerel deposuna yazar. Bu desen, bağımlılığı gevşek tutarken mevcut kullanıcı, sepet içeriği veya aktif navigasyon durumu gibi paylaşılan veriler için tek bir doğruluk kaynağı sağlar.
İletişim katmanı açıkça tasarlanmalı ve belgelenmelidir. Ekiplerin olay adları, yük şekilleri ve paylaşılan durum ile yerel durum arasındaki sınırlar üzerinde anlaşması gerekir. Bu anlaşma olmadan, mikro önyüzler birbirlerinin iç durumuna örtük bağımlılıklar geliştirir ve mikro önyüzlerin tüm karmaşıklığına sahip olan ancak hiçbir faydasını sunmayan dağıtık bir monolit ortaya çıkar.
Yönlendirme Stratejileri
Mikro önyüz mimarisinde yönlendirme iki soruyu yanıtlamalıdır. Mevcut rota hangi mikro önyüze ait? Ve mikro önyüzler arasında gezinme nasıl çalışır? Cevaplar, merkezi bir kabuk yönlendirici, dağıtık bir yönlendirme yaklaşımı veya hibrit bir strateji kullanmanıza bağlıdır.
Merkezi yönlendirme stratejisi, üst düzey yönlendiriciye sahip bir kabuk uygulaması kullanır. Kabuk, rota haritasını tanımlar, her URL kalıbı için hangi mikro önyüzün bağlanacağını belirler ve bağlanan mikro önyüze rota parametrelerini iletir. Her mikro önyüz, kendi alanı içindeki alt gezinme için kendi dahili yönlendiricisine sahiptir. Kabuk yönlendirici, alanlar arası gezinmeyi yönetir; mikro önyüz yönlendiricileri ise alan içi gezinmeyi yönetir.
Dağıtık yönlendirme stratejisi, her mikro önyüze kendi rotalarının sahipliğini verir. Kabuk yine de üst düzey URL-mikro-önyüz eşlemesini yönetir ancak her mikro önyüz, alt rotalarını ve dahili navigasyonunu bağımsız olarak yönetir. Kabuktaki bir navigasyon kütüphanesi, geçmiş değişikliklerini koordine eder ve URL çubuğunun yalnızca aktif mikro önyüzü değil, tüm uygulamanın mevcut durumunu yansıtmasını sağlar.
Olay tabanlı yönlendirme stratejisi, navigasyonu koordine etmek için iletişim veri yolunu kullanır. Bir mikro önyüz, başka bir mikro önyüze ait bir rotaya gitmesi gerektiğinde, veri yolunda bir navigate olayı yayar. Kabuk bu olayları dinler ve navigasyonu gerçekleştirir, bu da hedef mikro önyüzün bağlanmasını sağlar. Bu yaklaşım, yönlendirme endişelerini mikro önyüzlerin dışında tutar ve navigasyon mantığını kabukta merkezileştirir.
- Merkezi yönlendirme: Kabuk rota haritasına sahiptir, mikro önyüzler yalnızca dahili navigasyonu yönetir. Küçük ekipler ve basit alan sınırları için en iyisidir.
- Dağıtık yönlendirme: Her mikro önyüz kendi alt rotalarını yönetir. Açıkça ayrılmış alanlara sahip büyük ekipler için en iyisidir.
- Olay tabanlı yönlendirme: Navigasyon, paylaşılan bir olay veri yolu aracılığıyla koordine edilir. Mikro önyüzlerin farklı çerçeveler kullandığı çok dilli mimariler için en iyisidir.
- Hibrit yönlendirme: Kabuk üst düzey alan rotalarını yönetir, mikro önyüzler alt rotaları yönetir. Çoğu üretim uygulaması için en iyisidir.
Dağıtım ve Sürümleme
Dağıtım bağımsızlığı, mikro önyüzleri benimsemenin temel motivasyonudur. Her ekip, diğer ekiplerle koordinasyon kurmadan ve genel uygulamanın istikrarını etkilemeden kendi mikro önyüzünü dağıtabilmelidir. Bunu başarmak, dağıtım hattının, barındırma stratejisinin ve sürümleme şemasının dikkatli bir şekilde tasarlanmasını gerektirir.
En basit dağıtım modeli, ayrı barındırmadır. Her mikro önyüz kendi URL'sine veya bulut depolama alanına dağıtılır. Kabuk, her mikro önyüzü çalışma zamanında kendi URL'sinden yükler. Bu model maksimum bağımsızlık sağlar çünkü her ekip kendi altyapısını, kendi CI/CD hattını ve kendi geri alma stratejisini kontrol eder. Kabuğun, bir mikro önyüz güncellendiğinde yeniden dağıtılması gerekmez çünkü en son sürümü dinamik olarak yükler.
Ayrı barındırma modeli yeni bir zorluk ortaya çıkarır: geriye dönük uyumluluğu sağlamak için dağıtımları koordine etmek. Ödeme mikro önyüzü kabuktan belirli bir prop şekli bekliyorsa ve kabuğun bir sonraki dağıtımı bu prop şeklini değiştirirse, ödeme mikro önyüzü de güncellenene kadar bozulur. Çözüm, entegrasyon sözleşmesini — tipik olarak kabuktan her mikro önyüze iletilen prop'lar — sürümlemek ve kırıcı değişiklikler için semantik sürümleme uygulamaktır.
Canary dağıtımlar ve kademeli yayınlar, mikro önyüzlerle daha kolaydır çünkü her mikro önyüz bağımsız olarak dağıtılabilir. Bir ekip, mikro önyüzünün yeni bir sürümünü kullanıcıların yüzde beşine sunabilir, hata oranlarını ve performans metriklerini izleyebilir ve ardından her şey yolunda görünüyorsa yayını kademeli olarak artırabilir. Bir sorun tespit edilirse, ekip uygulamanın başka bir bölümünü etkilemeden mikro önyüzünü geri alır.
Kabukta sürüm sabitleme, acil durumlar için bir kaçış kapağı sağlar. Bir mikro önyüzün yeni bir dağıtımı testte yakalanmayan kırıcı bir değişiklik getirirse, kabuk önceki sürümü sabitleyip istikrarı sağlarken ekip sorunu çözer. Sabitleme mekanizması tipik olarak, her mikro önyüzü belirli bir dağıtılmış sürüme eşleyen bir yapılandırma dosyası veya ortam değişkenidir.
Monorepo ve Çoklu Repo Yaklaşımları
Mikro önyüzler için depo yapısı, önyüz topluluğunda tartışmalı bir konudur. Monorepo lehine ve ayrı depolar lehine argümanların her ikisi de geçerlidir ve doğru seçim ekip büyüklüğüne, organizasyonel olgunluğa ve araç tercihlerine bağlıdır.
Bir monorepo, tüm mikro önyüzleri dizinlere göre düzenlenmiş tek bir depoda tutar. Her mikro önyüzün kendi package.json'u, kendi derleme yapılandırması ve kendi dizini vardır. Monorepo yaklaşımı, bağımlılıkları yönetmek, derlemeleri çalıştırmak ve mikro önyüzler arasında görevleri düzenlemek için Turborepo, Nx, Lerna veya pnpm workspaces gibi araçları kullanır.
- Paylaşılan araç yapılandırması kolaydır: tüm mikro önyüzler için tek bir ESLint yapılandırması, tek bir TypeScript yapılandırması, tek bir Prettier yapılandırması.
- Çapraz kesen yeniden düzenlemeler daha basittir çünkü her mikro önyüzün kodu tek bir yerdedir.
- Bağımlılık yönetimi merkezileştirilir ve mikro önyüzler arasında sürüm uyuşmazlığı riski azalır.
- Bir değişiklik birden fazla alanı etkilediğinde mikro önyüzler arasında atomik commit'ler mümkündür.
Çoklu repo yaklaşımı, her mikro önyüzü kendi CI/CD hattı ve kendi araç yapılandırmasıyla birlikte kendi deposuna koyar. Ekipler, yığınları ve sürüm süreçleri üzerinde tam özerkliğe sahiptir. React'ten Preact'e geçmek isteyen bir ekip, mikro önyüz kabukta hâlâ doğru şekilde işlendiği sürece diğer ekiplerle koordinasyon kurmadan bunu yapabilir.
- Ekipler, geliştirme iş akışları ve araç seçimleri üzerinde tam özerkliğe sahiptir.
- Depo boyutu küçük kalır, bu da clone sürelerini hızlı ve CI hatlarını verimli kılar.
- Özel bir monorepo aracı gerekmez. Standart Git iş akışları ve npm kayıtları yeterlidir.
- Bir mikro önyüzdeki kırıcı değişiklik, başka bir mikro önyüzün derlemesini bozamaz.
Sektördeki eğilim, özellikle paylaşılan bir tasarım sistemi veya paylaşılan araçlar kullanan kuruluşlarda, mikro önyüz mimarileri için monorepo'lar yönündedir. Birden fazla depoda değişiklikleri koordine etmenin operasyonel yükü, özellikle aynı lokasyonda çalışan ve benzer teknoloji yığınları kullanan ekipler için özerklik faydalarından genellikle daha ağırdır. Ancak farklı çerçeveler kullanan dağıtık ekiplere sahip kuruluşlar için çoklu repo daha iyi bir seçim olmaya devam etmektedir.
Performans Değerlendirmeleri
Mikro önyüzler, monolitik bir uygulamaya kıyasla doğal bir performans yükü getirir. Her mikro önyüz kendi JavaScript paketini, kendi CSS'ini ve potansiyel olarak kendi çerçeve çalışma zamanını yükler. Tarayıcı daha fazla kod indirmeli, ayrıştırmalı ve çalıştırmalıdır. Ağ üzerinden aktarılan toplam bayt sayısı artar ve ilk sayfa yüklemesi için etkileşime geçme süresi uzar.
Modül Federasyonu'ndaki paylaşılan bağımlılık mekanizması, kütüphanelerin yalnızca bir kez yüklenmesini sağlayarak bu yükü azaltır. Ancak uygulama kodu — her mikro önyüzün bileşenleri, araçları ve iş mantığı — paylaşılmaz. Kullanıcı bir oturum sırasında üç farklı mikro önyüzde gezinti yaparsa, yalnızca biriyle etkileşime girse bile üçünün de uygulama kodunu indirir.
Her mikro önyüz içinde kod bölme esastır. Her mikro önyüz kendi rotalarını, kendi ağır bileşenlerini ve kendi üçüncü taraf kütüphanelerini tembel yüklemelidir. Grafik kütüphanesi içeren bir yönetim paneli mikro önyüzü, bu kütüphaneyi kullanıcı grafik gösteren bir sayfaya gerçekten gidene kadar yüklememelidir. Bu, monolitik uygulamalarda kullanılan kod bölme pratiklerini her mikro önyüz sınırı içinde uygulamakla aynı şeydir.
Önceden getirme, mikro önyüz mimarileri için değerli bir optimizasyondur. Kullanıcı ödeme mikro önyüzünde bir rotaya gittiğinde, kabuk kullanıcının muhtemelen sırada sipariş onayı mikro önyüzüne gideceğini tahmin edebilir ve kaynaklarını arka planda indirmeye başlayabilir. Önceden getirme stratejisi, navigasyon kalıpları hakkındaki varsayımlarla değil, gerçek kullanıcı davranışı verileriyle belirlenmelidir.
Kritik işleme yolu korunmalıdır. Kabuk uygulaması, monolitik bir uygulama kadar hızlı işlenmelidir. Bu, kabuğun hafif olması gerektiği anlamına gelir — minimal JavaScript, minimal CSS, minimal bağımlılık. Kabuk ilk işlemeden sorumludur ve yavaş mikro önyüzler bunu geciktirmemelidir. Her mikro önyüz asenkron olarak yüklenmeli ve hazır olana kadar bir yükleme durumu göstermelidir.
Performans bütçeleri yalnızca uygulama düzeyinde değil, mikro önyüz düzeyinde de belirlenmelidir. Her ekip, kendi mikro önyüzü için maksimum paket boyutunu, maksimum etkileşime geçme süresini ve maksimum bellek ayak izini bilmelidir. Bu bütçelerin ihlalleri, monolitik bir uygulamada olduğu gibi CI hattını başarısız kılmalıdır.
Mikro Önyüzleri Test Etme
Bir mikro önyüz mimarisini test etmek, üç düzeyde test gerektirir: bireysel mikro önyüzlerin izole olarak test edilmesi, mikro önyüzler arasındaki entegrasyonun test edilmesi ve birleştirilmiş uygulamanın bir bütün olarak test edilmesi. Her düzeyin farklı araçları, farklı hedefleri ve farklı sahiplik modelleri vardır.
Her mikro önyüz içindeki birim testleri ve bileşen testleri, diğer herhangi bir önyüz uygulamasıyla aynı kalıpları izler. Her ekip kendi mikro önyüzünü test etmekten sorumludur ve testler ekibin kendi CI hattında çalışır. Tek fark, her mikro önyüzün kabuğun ve diğer mikro önyüzlerin güvenilmez olduğu varsayımıyla test edilmesi gerektiğidir — kabuğun beklenmeyen prop'lar sağlaması veya bir iletişim olayının gelmemesi durumunda mikro önyüzün zarif bir şekilde bozulduğunu doğrulayan savunma amaçlı testler.
Mikro önyüzler arasındaki entegrasyon testi en zor düzeydir. Test, kabuğu ve birden fazla mikro önyüzü aynı anda yüklemeli, mikro önyüz sınırlarını geçen kullanıcı etkileşimlerini simüle etmeli ve birleştirilmiş davranışın doğru olduğunu doğrulamalıdır. Cypress ve Playwright gibi araçlar bu düzeyde mükemmeldir çünkü gerçek bir tarayıcıda çalışır ve tam birleştirilmiş uygulamayla etkileşime girebilir.
Entegrasyon testi için etkili bir strateji, her mikro önyüzün kendi URL'sine dağıtıldığı ve kabuğun bunları yükleyecek şekilde yapılandırıldığı bir test ortamında üretim benzeri bir dağıtım çalıştırmaktır. Test paketi daha sonra bu dağıtıma karşı çalışarak mikro önyüz sınırlarını geçen gerçek kullanıcı yolculuklarını simüle eder. Bu, izole testlerde görünmeyen sorunları yakalar — bir mikro önyüzün başka bir mikro önyüz onunla iletişim kurmaya çalışmadan önce başlatmayı tamamlamadığı zamanlama hataları veya bir mikro önyüzdeki CSS güncellemesinin diğerinin düzenini etkilediği stil bozulmaları.
Görsel regresyon testi, mikro önyüz mimarileri için özellikle önemlidir. Paylaşılan tasarım sistemi kendi görsel regresyon paketine sahip olmalıdır. Her mikro önyüz, kendi sayfaları için görsel regresyon testlerine sahip olmalıdır. Birleştirilmiş uygulama ise kritik kullanıcı yolculukları için görsel regresyon testlerine sahip olmalıdır. Percy, Chromatic veya Loki gibi araçlar CI hattına entegre olur ve görsel bozulmaları otomatik olarak yakalar.
Mikro Önyüzler Ne Zaman KULLANILMAMALI
Mikro önyüzler her proje için doğru mimari değildir. Getirdikleri karmaşıklık — operasyonel yük, performans maliyetleri, koordinasyon gereksinimleri ve hata ayıklama zorluğu — yalnızca belirli organizasyonel ihtiyaçlarla haklı çıkarılır. Mikro önyüzleri ihtiyaç duyulmayan bir projeye uygulamak, gereksiz sürtüşme yaratır ve hiçbir fayda sağlamadan geliştirmeyi yavaşlatır.
Tek bir uygulama oluşturan küçük bir ekibin mikro önyüzlere ihtiyacı yoktur. Mimari, her biri belirli bir alandan sorumlu birden fazla ekibi olan kuruluşlar için tasarlanmıştır. Tüm önyüzünüz üç veya dört geliştirici tarafından oluşturulabiliyorsa, iyi organize edilmiş modüllere sahip monolitik bir uygulama, mikro önyüz mimarisinden daha üretken, daha hızlı ve daha kolay bakım yapılabilir olacaktır.
Sıkı bağlı alanlara sahip bir uygulama, mikro önyüzler için zayıf bir adaydır. Uygulamanızdaki her özellik diğer her özellikle etkileşime giriyorsa — ürün kataloğu, sepet ve ödeme o kadar iç içe geçmişse ki temiz bir şekilde ayrılamıyorsa — bunları mikro önyüzlere bölmek, monolitte sahip olduğunuz doğrudan erişimi simüle eden karmaşık iletişim katmanları oluşturmanıza neden olur. Bu, dağıtık monolit anti-desenidir.
Operasyonel olgunluğu olmayan bir kuruluş, mikro önyüzlerle zorlanacaktır. Mimari, güçlü DevOps pratikleri, otomatik test, izleme ve olay müdahalesi gerektirir. Her ekip bağımsız olarak dağıtabilmeli ve hızlıca geri alabilmelidir. Kuruluşunuz henüz bu pratiklere yatırım yapmadıysa, monolitik bir uygulama bağlamında bunlara odaklanmak, mikro önyüzleri benimsemekten daha iyi bir yatırımdır.
Katı yükleme süresi gereksinimleri olan performans kritik uygulamalar, mikro önyüzlerin getirdiği yüke tolerans göstermeyebilir. Her milisaniyenin önemli olduğu durumlarda — örneğin, gerçek zamanlı bir işlem panosu veya video akış arayüzü — mikro önyüzlerin getirdiği ek ağ istekleri ve JavaScript ayrıştırma süresi, uygulamayı performans bütçesinin ötesine taşıyabilir.
- Ekibinizde dörtten az önyüz geliştiricisi varsa.
- Uygulamanın beşten az belirgin alan sınırı varsa.
- Ekibin mikroservisler veya dağıtık sistemler konusunda deneyimi yoksa.
- Kuruluşta otomatik CI/CD ve izleme altyapısı yoksa.
- Uygulamanın karşılanması zaten zor olan katı performans bütçeleri varsa.
- Özellikler sıkı bağlıysa ve alanlara temiz bir şekilde ayrılamıyorsa.
Mikro önyüzler, teknik bir mimari olarak tezahür eden organizasyonel bir karardır. Sağladıkları organizasyonel bağımsızlığa — farklı ekipler, farklı sürüm takvimleri, farklı teknoloji seçimleri — ihtiyacınız yoksa, teknik yük maliyete değmez.
Sonuç
Mikro önyüzler, önyüz geliştirmeyi birden fazla ekip arasında ölçeklendirmesi gereken kuruluşlar için güçlü bir mimari desendir. Mimari gerçek faydalar sağlar: bağımsız dağıtılabilirlik, ekip özerkliği, teknoloji özgürlüğü ve özellikleri farklı takvimlerde yayınlama yeteneği. Bu faydalar, mimari doğru probleme uygulandığında gerçek ve ölçülebilirdir.
Mikro önyüzlerle başarının anahtarı, onlara önce organizasyonel bir çözüm, sonra teknik bir çözüm olarak yaklaşmaktır. Mimari, zarif bir şekilde ayrıştırılmış kod üretmek için değil, ekip bağımsızlığını mümkün kılmak için vardır. Modül Federasyonu ve iframe'ler, monorepo ve çoklu repo, olay veri yolu ve paylaşılan depo arasındaki her teknik karar, uyumlu bir kullanıcı deneyimini korurken ekip hızını maksimize etme hedefiyle alınmalıdır.
Küçük başlayın. Net bir alan sınırı olan ve onu bağımsız olarak sahiplenmeye istekli bir ekibi olan tek bir mikro önyüzle başlayın. Dağıtım hattının çalıştığını, performansın kabul edilebilir olduğunu ve ekibin daha hızlı yayın yapabildiğini kanıtlayın. Ardından kademeli olarak genişleyin. Mikro önyüzler, ya hep ya hiç gerektiren bir mimari değildir. Hibrit bir yaklaşım — aksi halde monolitik bir uygulama içinde bir veya iki mikro önyüz — genellikle en iyi başlangıç noktasıdır.
Mikro önyüz benimsemesinde en yaygın başarısızlık şekli, erken soyutlamadır. Ekipler, gerçek ihtiyaçlarını anlamadan önce ayrıntılı orkestrasyon katmanları, paylaşılan durum sistemleri ve çapraz kesen altyapılar oluşturur. Mümkün olan en basit entegrasyonla başlayın — mikro önyüzleri bir script etiketi veya Modül Federasyonu aracılığıyla yükleyen bir kabuk — ve basit yaklaşım yetersiz kaldığında karmaşıklık ekleyin. Doğru soyutlama seviyesi, önceden yapılan tasarımla değil, gerçek kullanımla kendini gösterir.
Modül Federasyonu, mikro önyüzleri her zamankinden daha erişilebilir hale getirdi ancak temel sorular organizasyonel olmaya devam ediyor. Ekiplerinizin bağımsız olarak dağıtım yapması gerekiyor mu? Kuruluşunuz operasyonel karmaşıklığı kaldırabilir mi? Alanlarınız temiz bir şekilde ayrılabilir mi? Bu sorulara evet diyen ekipler, mikro önyüzleri dönüştürücü bulacaktır. Hayır diyen ekipler ise onları sinir bozucu bulacaktır. Mimarın kendisi tarafsızdır — değeri tamamen uygulandığı bağlama bağlıdır.
