Webpack 5'teki JavaScript Module Federation ile mikro-ön yüzlerin gücünü ortaya çıkarın. Ölçeklenebilir, bakımı kolay ve bağımsız web uygulamaları oluşturmayı öğrenin.
Webpack 5 ile JavaScript Module Federation: Mikro-ön yüzler için Kapsamlı Bir Rehber
Sürekli gelişen web geliştirme dünyasında, büyük ve karmaşık uygulamalar oluşturmak göz korkutucu bir görev olabilir. Geleneksel monolitik mimariler genellikle artan geliştirme süresine, dağıtım darboğazlarına ve kod kalitesini sürdürmedeki zorluklara yol açar. Mikro-ön yüzler, bu zorlukların üstesinden gelmek için güçlü bir mimari model olarak ortaya çıkmıştır ve ekiplerin daha büyük bir web uygulamasının bağımsız parçalarını oluşturmasına ve dağıtmasına olanak tanır. Mikro-ön yüzleri uygulamak için en umut verici teknolojilerden biri, Webpack 5'te tanıtılan JavaScript Module Federation'dır.
Mikro-ön yüzler (Micro-frontends) Nedir?
Mikro-ön yüzler, bir ön yüz uygulamasının, farklı ekipler tarafından otonom olarak geliştirilebilen, test edilebilen ve dağıtılabilen daha küçük, bağımsız birimlere ayrıldığı bir mimari tarzdır. Her bir mikro-ön yüz, belirli bir iş alanından veya özellikten sorumludur ve tam kullanıcı arayüzünü oluşturmak için çalışma zamanında bir araya getirilirler.
Bunu bir şirket gibi düşünün: dev bir geliştirme ekibine sahip olmak yerine, belirli alanlara odaklanan birden fazla küçük ekibiniz vardır. Her ekip bağımsız olarak çalışabilir, bu da daha hızlı geliştirme döngüleri ve daha kolay bakım sağlar. Amazon gibi büyük bir e-ticaret platformunu düşünün; farklı ekipler ürün kataloğunu, alışveriş sepetini, ödeme sürecini ve kullanıcı hesabı yönetimini yönetebilir. Bu özelliklerin hepsi bağımsız mikro-ön yüzler olabilir.
Mikro-ön yüzlerin Faydaları:
- Bağımsız Dağıtımlar: Ekipler, mikro-ön yüzlerini uygulamanın diğer bölümlerini etkilemeden bağımsız olarak dağıtabilirler. Bu, dağıtım riskini azaltır ve daha hızlı sürüm döngülerine olanak tanır.
- Teknolojiden Bağımsız Olma: Farklı mikro-ön yüzler, farklı teknolojiler veya framework'ler (ör. React, Angular, Vue.js) kullanılarak oluşturulabilir. Bu, ekiplerin kendi özel ihtiyaçları için en iyi teknolojiyi seçmelerine ve tüm uygulamayı yeniden yazmak zorunda kalmadan yeni teknolojileri kademeli olarak benimsemelerine olanak tanır. Bir ekibin ürün kataloğu için React kullandığını, başka bir ekibin pazarlama açılış sayfaları için Vue.js kullandığını ve üçüncü bir ekibin ödeme süreci için Angular kullandığını hayal edin.
- Gelişmiş Ekip Özerkliği: Ekiplerin kendi mikro-ön yüzlerinin tam mülkiyetine sahip olması, artan özerkliğe, daha hızlı karar vermeye ve gelişmiş geliştirici verimliliğine yol açar.
- Artırılmış Ölçeklenebilirlik: Mikro-ön yüzler, bireysel mikro-ön yüzleri farklı sunucularda dağıtarak uygulamanızı yatay olarak ölçeklendirmenize olanak tanır.
- Kodun Yeniden Kullanılabilirliği: Paylaşılan bileşenler ve kütüphaneler, mikro-ön yüzler arasında kolayca paylaşılabilir.
- Daha Kolay Bakım: Daha küçük kod tabanlarının anlaşılması, bakımı ve hatalarının ayıklanması genellikle daha kolaydır.
Mikro-ön yüzlerin Zorlukları:
- Artan Karmaşıklık: Birden fazla mikro-ön yüzü yönetmek, özellikle iletişim, durum yönetimi ve dağıtım açısından genel mimariye karmaşıklık katabilir.
- Performans Yükü: Birden fazla mikro-ön yüzü yüklemek, özellikle düzgün bir şekilde optimize edilmemişlerse performans yükü oluşturabilir.
- Kesimler Arası Endişeler (Cross-Cutting Concerns): Kimlik doğrulama, yetkilendirme ve tema gibi kesimler arası endişeleri ele almak, bir mikro-ön yüz mimarisinde zorlayıcı olabilir.
- Operasyonel Yük: Birden fazla mikro-ön yüzün dağıtımını ve izlenmesini yönetmek için olgun DevOps uygulamaları ve altyapısı gerektirir.
JavaScript Module Federation Nedir?
JavaScript Module Federation, ayrı ayrı derlenmiş JavaScript uygulamaları arasında çalışma zamanında kod paylaşmanıza olanak tanıyan bir Webpack 5 özelliğidir. Uygulamanızın parçalarını, npm gibi merkezi bir depoya yayınlamaya gerek kalmadan diğer uygulamalar tarafından tüketilebilecek "modüller" olarak sunmanıza olanak tanır.
Module Federation'ı, her uygulamanın kendi işlevselliğini katabildiği ve diğer uygulamalardan işlevsellik tüketebildiği, federe bir uygulama ekosistemi oluşturmanın bir yolu olarak düşünün. Bu, derleme zamanı bağımlılıklarına olan ihtiyacı ortadan kaldırır ve gerçekten bağımsız dağıtımlara olanak tanır.
Örneğin, bir tasarım sistemi ekibi, kullanıcı arayüzü bileşenlerini modül olarak sunabilir ve farklı uygulama ekipleri bu bileşenleri npm paketleri olarak yüklemeye gerek kalmadan doğrudan tasarım sistemi uygulamasından tüketebilir. Tasarım sistemi ekibi bileşenleri güncellediğinde, değişiklikler tüm tüketen uygulamalara otomatik olarak yansıtılır.
Module Federation'daki Temel Kavramlar:
- Host: Uzak (remote) modülleri tüketen ana uygulama.
- Remote: Diğer uygulamalar tarafından tüketilmek üzere modüller sunan bir uygulama.
- Paylaşılan Modüller: Host ve remote uygulamalar arasında paylaşılan modüller (ör. React, Lodash). Module Federation, her modülün yalnızca bir sürümünün yüklenmesini sağlamak için paylaşılan modüllerin sürüm yönetimini ve tekilleştirilmesini otomatik olarak halledebilir.
- Sunulan Modüller (Exposed Modules): Bir remote uygulamadan diğer uygulamalar tarafından tüketilmek üzere sunulan belirli modüller.
- RemoteEntry.js: Webpack tarafından oluşturulan ve bir remote uygulamanın sunulan modülleri hakkındaki meta verileri içeren bir dosya. Host uygulama, remote modülleri keşfetmek ve yüklemek için bu dosyayı kullanır.
Webpack 5 ile Module Federation Kurulumu: Pratik Bir Rehber
Şimdi Webpack 5 ile Module Federation kurmanın pratik bir örneğini inceleyelim. İki basit uygulama oluşturacağız: bir Host (Ana) uygulama ve bir Remote (Uzak) uygulama. Remote uygulama bir bileşen sunacak ve Host uygulama bunu tüketecektir.
1. Proje Kurulumu
Uygulamalarınız için iki ayrı dizin oluşturun: `host` ve `remote`.
```bash mkdir host remote cd host npm init -y npm install webpack webpack-cli webpack-dev-server html-webpack-plugin --save-dev npm install react react-dom cd ../remote npm init -y npm install webpack webpack-cli webpack-dev-server html-webpack-plugin --save-dev npm install react react-dom ```2. Remote (Uzak) Uygulama Yapılandırması
`remote` dizininde aşağıdaki dosyaları oluşturun:
- `src/index.js`: Uygulamanın giriş noktası.
- `src/RemoteComponent.jsx`: Sunulacak olan bileşen.
- `webpack.config.js`: Webpack yapılandırma dosyası.
src/index.js:
```javascript import React from 'react'; import ReactDOM from 'react-dom/client'; import RemoteComponent from './RemoteComponent'; const App = () => (Remote Application
src/RemoteComponent.jsx:
```javascript import React from 'react'; const RemoteComponent = () => (This is a Remote Component!
Rendered from the Remote Application.
webpack.config.js:
```javascript const HtmlWebpackPlugin = require('html-webpack-plugin'); const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin'); const path = require('path'); module.exports = { entry: './src/index', mode: 'development', devServer: { port: 3001, static: { directory: path.join(__dirname, 'dist'), }, }, output: { publicPath: 'auto', }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-react', '@babel/preset-env'], }, }, }, ], }, plugins: [ new ModuleFederationPlugin({ name: 'remote', filename: 'remoteEntry.js', exposes: { './RemoteComponent': './src/RemoteComponent', }, shared: { react: { singleton: true, eager: true }, 'react-dom': { singleton: true, eager: true }, }, }), new HtmlWebpackPlugin({ template: './public/index.html', }), ], resolve: { extensions: ['.js', '.jsx'], }, }; ```Temel HTML yapısıyla `public/index.html` dosyasını oluşturun. Önemli olan kısım `
`3. Host (Ana) Uygulama Yapılandırması
`host` dizininde aşağıdaki dosyaları oluşturun:
- `src/index.js`: Uygulamanın giriş noktası.
- `webpack.config.js`: Webpack yapılandırma dosyası.
src/index.js:
```javascript import React, { Suspense } from 'react'; import ReactDOM from 'react-dom/client'; const RemoteComponent = React.lazy(() => import('remote/RemoteComponent')); const App = () => (Host Application
webpack.config.js:
```javascript const HtmlWebpackPlugin = require('html-webpack-plugin'); const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin'); const path = require('path'); module.exports = { entry: './src/index', mode: 'development', devServer: { port: 3000, static: { directory: path.join(__dirname, 'dist'), }, }, output: { publicPath: 'auto', }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-react', '@babel/preset-env'], }, }, }, ], }, plugins: [ new ModuleFederationPlugin({ name: 'host', remotes: { remote: 'remote@http://localhost:3001/remoteEntry.js', }, shared: { react: { singleton: true, eager: true }, 'react-dom': { singleton: true, eager: true }, }, }), new HtmlWebpackPlugin({ template: './public/index.html', }), ], resolve: { extensions: ['.js', '.jsx'], }, }; ```Temel HTML yapısıyla `public/index.html` dosyasını oluşturun (remote uygulamasına benzer şekilde). Önemli olan kısım `
`4. Babel Kurulumu
Hem `host` hem de `remote` dizinlerinde Babel bağımlılıklarını yükleyin:
```bash npm install --save-dev @babel/core @babel/preset-env @babel/preset-react babel-loader ```5. Uygulamaları Çalıştırma
Hem `host` hem de `remote` dizinlerinde, `package.json` dosyasına aşağıdaki script'i ekleyin:
```json "scripts": { "start": "webpack serve" } ```Şimdi her iki uygulamayı da başlatın:
```bash cd remote npm start cd ../host npm start ```Tarayıcınızı açın ve `http://localhost:3000` adresine gidin. İçinde Remote Component'in render edildiği Host uygulamasını görmelisiniz.
Temel Yapılandırma Seçeneklerinin Açıklaması:
- `name`: Uygulama için benzersiz bir isim.
- `filename`: Sunulan modüller hakkındaki meta verileri içerecek dosyanın adı (ör. `remoteEntry.js`).
- `exposes`: Hangi modüllerin sunulması gerektiğini belirten, modül adlarından dosya yollarına bir eşlem.
- `remotes`: Her bir remote uygulamanın remoteEntry.js dosyasının nerede bulunacağını belirten, remote uygulama adlarından URL'lere bir eşlem.
- `shared`: Host ve remote uygulamalar arasında paylaşılması gereken modüllerin bir listesi. `singleton: true` seçeneği, her paylaşılan modülün yalnızca bir örneğinin yüklenmesini sağlar. `eager: true` seçeneği, paylaşılan modülün hevesli bir şekilde (yani diğer modüllerden önce) yüklenmesini sağlar.
İleri Seviye Module Federation Teknikleri
Module Federation, daha da karmaşık mikro-ön yüz mimarileri oluşturmanıza yardımcı olabilecek birçok gelişmiş özellik sunar.
Dinamik Remotes
Webpack yapılandırmasında remote uygulamaların URL'lerini sabit olarak kodlamak yerine, bunları çalışma zamanında dinamik olarak yükleyebilirsiniz. Bu, host uygulamasını yeniden derlemeye gerek kalmadan remote uygulamaların konumunu kolayca güncellemenize olanak tanır.
Örneğin, remote uygulamaların URL'lerini bir yapılandırma dosyasında veya bir veritabanında saklayabilir ve bunları JavaScript kullanarak dinamik olarak yükleyebilirsiniz.
```javascript // webpack.config.js içinde remotes: { remote: `promise new Promise(resolve => { const urlParams = new URLSearchParams(window.location.search); const remoteUrl = urlParams.get('remote'); // remoteUrl'in 'http://localhost:3001/remoteEntry.js' gibi bir şey olduğunu varsayalım const script = document.createElement('script'); script.src = remoteUrl; script.onload = () => { // module federation'ın anahtarı, remote uygulamanın // remote'daki ismi kullanarak kullanılabilir olmasıdır resolve(window.remote); }; document.head.appendChild(script); })`, }, ```Artık host uygulamasını `?remote=http://localhost:3001/remoteEntry.js` gibi bir sorgu parametresiyle yükleyebilirsiniz.
Sürümlendirilmiş Paylaşılan Modüller
Module Federation, her modülün yalnızca bir uyumlu sürümünün yüklenmesini sağlamak için paylaşılan modüllerin sürüm yönetimini ve tekilleştirilmesini otomatik olarak halledebilir. Bu, özellikle çok sayıda bağımlılığı olan büyük ve karmaşık uygulamalarla uğraşırken önemlidir.
Webpack yapılandırmasında her paylaşılan modülün sürüm aralığını belirtebilirsiniz.
```javascript // webpack.config.js içinde shared: { react: { singleton: true, eager: true, requiredVersion: '^18.0.0' }, 'react-dom': { singleton: true, eager: true, requiredVersion: '^18.0.0' }, }, ```Özel Modül Yükleyiciler
Module Federation, farklı kaynaklardan veya farklı formatlarda modül yüklemek için kullanılabilecek özel modül yükleyicileri tanımlamanıza olanak tanır. Bu, bir CDN'den veya özel bir modül kayıt defterinden modül yüklemek için yararlı olabilir.
Mikro-ön yüzler Arasında Durum (State) Paylaşımı
Mikro-ön yüz mimarilerinin zorluklarından biri, farklı mikro-ön yüzler arasında durum paylaşımıdır. Bu zorluğun üstesinden gelmek için kullanabileceğiniz birkaç yaklaşım vardır:
- URL tabanlı durum yönetimi: Durumu URL'de saklayın ve mikro-ön yüzler arasında iletişim kurmak için URL'yi kullanın. Bu basit ve anlaşılır bir yaklaşımdır, ancak karmaşık durumlar için hantal hale gelebilir.
- Özel olaylar (Custom events): Mikro-ön yüzler arasında durum değişikliklerini yayınlamak için özel olayları kullanın. Bu, mikro-ön yüzler arasında gevşek bir bağ kurmaya olanak tanır, ancak olay aboneliklerini yönetmek zor olabilir.
- Paylaşılan durum yönetimi kütüphanesi: Tüm uygulamanın durumunu yönetmek için Redux veya MobX gibi paylaşılan bir durum yönetimi kütüphanesi kullanın. Bu, durumu yönetmek için merkezi ve tutarlı bir yol sağlar, ancak belirli bir durum yönetimi kütüphanesine bağımlılık getirebilir.
- Mesajlaşma Aracısı (Message Broker): Mikro-ön yüzler arasında iletişim ve durum paylaşımını kolaylaştırmak için RabbitMQ veya Kafka gibi bir mesajlaşma aracısı kullanın. Bu daha karmaşık bir çözümdür, ancak yüksek derecede esneklik ve ölçeklenebilirlik sunar.
Module Federation ile Mikro-ön yüzleri Uygulamak için En İyi Pratikler
Module Federation ile mikro-ön yüzleri uygularken akılda tutulması gereken bazı en iyi pratikler şunlardır:
- Her mikro-ön yüz için net sınırlar belirleyin: Her mikro-ön yüz, belirli bir iş alanından veya özellikten sorumlu olmalı ve iyi tanımlanmış arayüzlere sahip olmalıdır.
- Tutarlı bir teknoloji yığını kullanın: Module Federation, farklı mikro-ön yüzler için farklı teknolojiler kullanmanıza izin verse de, karmaşıklığı azaltmak ve sürdürülebilirliği artırmak için genellikle tutarlı bir teknoloji yığını kullanmak iyi bir fikirdir.
- Açık iletişim protokolleri oluşturun: Mikro-ön yüzlerin birbirleriyle nasıl etkileşime girmesi gerektiğine dair net iletişim protokolleri tanımlayın.
- Dağıtım sürecini otomatikleştirin: Mikro-ön yüzlerin bağımsız ve güvenilir bir şekilde dağıtılabilmesini sağlamak için dağıtım sürecini otomatikleştirin. CI/CD boru hatları ve kod olarak altyapı (infrastructure-as-code) araçlarını kullanmayı düşünün.
- Mikro-ön yüzlerinizin performansını izleyin: Herhangi bir performans darboğazını belirlemek ve gidermek için mikro-ön yüzlerinizin performansını izleyin. Google Analytics, New Relic veya Datadog gibi araçları kullanın.
- Sağlam hata yönetimi uygulayın: Uygulamanızın arızalara karşı dayanıklı olmasını sağlamak için sağlam hata yönetimi uygulayın.
- Merkezi olmayan bir yönetim modelini benimseyin: Genel tutarlılığı ve kaliteyi korurken, ekipleri kendi mikro-ön yüzleri hakkında karar vermeleri için güçlendirin.
Module Federation'ın Gerçek Dünya Uygulama Örnekleri
Özel vaka çalışmaları genellikle gizli olsa da, Module Federation'ın inanılmaz derecede yararlı olabileceği bazı genelleştirilmiş senaryolar şunlardır:
- E-ticaret Platformları: Daha önce de belirtildiği gibi, büyük e-ticaret platformları ürün kataloğu, alışveriş sepeti, ödeme süreci ve kullanıcı hesabı yönetimi için bağımsız mikro-ön yüzler oluşturmak üzere Module Federation'ı kullanabilir. Bu, farklı ekiplerin bu özellikler üzerinde bağımsız olarak çalışmasına ve uygulamanın diğer bölümlerini etkilemeden bunları dağıtmasına olanak tanır. Küresel bir platform, uzak modüller aracılığıyla farklı bölgeler için özellikleri özelleştirebilir.
- Finansal Hizmetler Uygulamaları: Finansal hizmetler uygulamaları genellikle birçok farklı özelliğe sahip karmaşık kullanıcı arayüzlerine sahiptir. Module Federation, farklı hesap türleri, ticaret platformları ve raporlama panoları için bağımsız mikro-ön yüzler oluşturmak için kullanılabilir. Belirli ülkelere özgü uyumluluk özellikleri Module Federation aracılığıyla sunulabilir.
- Sağlık Portalları: Sağlık portalları, hasta yönetimi, randevu planlama ve tıbbi kayıtlara erişim için bağımsız mikro-ön yüzler oluşturmak üzere Module Federation'ı kullanabilir. Farklı sigorta sağlayıcıları veya bölgeler için farklı modüller dinamik olarak yüklenebilir.
- İçerik Yönetim Sistemleri (CMS): Bir CMS, kullanıcıların üçüncü taraf geliştiricilerden uzak modüller yükleyerek web sitelerine özel işlevsellik eklemelerine olanak tanımak için Module Federation'ı kullanabilir. Farklı temalar, eklentiler ve widget'lar bağımsız mikro-ön yüzler olarak dağıtılabilir.
- Öğrenme Yönetim Sistemleri (LMS): Bir LMS, bağımsız olarak geliştirilen ve Module Federation aracılığıyla birleşik bir platforma entegre edilen kurslar sunabilir. Bireysel kurslardaki güncellemeler, platform genelinde yeniden dağıtım gerektirmez.
Sonuç
Webpack 5'teki JavaScript Module Federation, mikro-ön yüz mimarileri oluşturmak için güçlü ve esnek bir yol sağlar. Ayrı ayrı derlenmiş JavaScript uygulamaları arasında çalışma zamanında kod paylaşmanıza olanak tanır, bu da bağımsız dağıtımları, teknoloji çeşitliliğini ve gelişmiş ekip özerkliğini mümkün kılar. Bu kılavuzda belirtilen en iyi pratikleri izleyerek, ölçeklenebilir, sürdürülebilir ve yenilikçi web uygulamaları oluşturmak için Module Federation'dan yararlanabilirsiniz.
Ön yüz geliştirmenin geleceği şüphesiz modüler ve dağıtık mimarilere doğru eğilmektedir. Module Federation, bu modern sistemleri oluşturmak için çok önemli bir araç sağlar ve ekiplerin daha yüksek hız, esneklik ve dayanıklılıkla karmaşık uygulamalar oluşturmasını sağlar. Teknoloji olgunlaştıkça, daha da yenilikçi kullanım durumlarının ve en iyi pratiklerin ortaya çıkmasını bekleyebiliriz.