Mikro-frontendlar uchun Module Federation-ga chuqur kirish. Ish vaqtida kod va bog'liqliklarni qanday almashish, to'plam hajmini kamaytirish va mustaqil joylashtirishni yo'lga qo'yishni o'rganing.
Module Federation: Mikro-Frontendlarda Ish vaqtida modullarni almashish bo'yicha to'liq qo'llanma
Doimiy rivojlanib borayotgan veb-dasturlash landshaftida biz muhim arxitekturaviy o'zgarishlarga guvoh bo'ldik. Biz masshtablashuvchanlik va jamoa avtonomiyasini izlab, monolit arxitekturalardan backend mikroservislariga sayohat qildik. Endi, xuddi shu inqilob frontendni o'zgartirmoqda. Mikro-frontendlar davri keldi va uning markazida buni amaliy qiladigan kuchli texnologiya yotadi: Module Federation.
Mikro-frontendlarning asosiy muammosini aytish har doim oson, ammo hal qilish qiyin bo'lgan: bir nechta, mustaqil ravishda joylashtirilgan ilovalardan sekin, shishirilgan va boshqarib bo'lmaydigan chalkashlik yaratmasdan yagona, yaxlit foydalanuvchi tajribasini qanday yaratasiz? Komponent kutubxonalari yoki React kabi freymvorklar kabi umumiy kodni versiyalash bilan bog'liq bosh og'riqlarisiz yoki muvofiqlashtirilgan relizlarga majburlamasdan qanday almashamiz?
Bu muammoni Module Federation nafis hal qiladi. Webpack 5 da taqdim etilgan bu shunchaki yana bir xususiyat emas; bu veb-ilovalarni yaratish va joylashtirish haqidagi fikrlash tarzimizdagi paradigma o'zgarishidir. Ushbu keng qamrovli qo'llanma Module Federation-ning nima, nima uchun va qanday ishlashini, uning eng o'zgartiruvchi qobiliyati: ish vaqtida modullarni almashishga e'tibor qaratgan holda o'rganadi.
Tezkor eslatma: Mikro-frontendlar nima?
Module Federation mexanikasiga sho'ng'ishdan oldin, mikro-frontendlar deganda nimani nazarda tutayotganimizni kelishib olaylik. Katta elektron tijorat veb-saytini tasavvur qiling. Monolit dunyoda butun frontend—mahsulot qidiruvi, mahsulot tafsilotlari, xarid savatchasi va to'lov jarayoni—yagona, katta ilovadir. To'lov tugmasiga kiritilgan o'zgartirish butun ilovani sinovdan o'tkazishni va qayta joylashtirishni talab qilishi mumkin.
Mikro-frontend arxitekturasi bu monolitni biznes domenlari bo'ylab ajratadi. Sizda bo'lishi mumkin:
- Qidiruv paneli va natijalar sahifasiga egalik qiluvchi Qidiruv Jamoasi.
- Mahsulot tafsilotlari va tavsiyalariga egalik qiluvchi Mahsulot Jamoasi.
- Xarid savatchasi va to'lov jarayoniga egalik qiluvchi To'lov Jamoasi.
Har bir jamoa o'z ilovasining qismini mustaqil ravishda yaratishi, sinovdan o'tkazishi va joylashtirishi mumkin. Bu bir nechta asosiy afzalliklarga olib keladi:
- Avtonom Jamoalar: Jamoalar o'z jadvallariga ko'ra ishlashi va relizlar chiqarishi mumkin, bu esa ishlab chiqishni tezlashtiradi.
- Mustaqil Joylashtirishlar: Tavsiyalar mexanizmidagi xatolik to'lov oqimidagi muhim yangilanishni to'sib qo'ymaydi.
- Texnologik Moslashuvchanlik: Qidiruv jamoasi Vue.js dan, mahsulot jamoasi esa React-dan foydalanishi mumkin, bu jamoalarga o'zlarining maxsus domeni uchun eng yaxshi vositani tanlash imkonini beradi (garchi bu ehtiyotkorlik bilan boshqarishni talab qilsa ham).
Biroq, bu yondashuv o'zining qiyinchiliklarini, asosan, almashish va izchillik bilan bog'liq muammolarni keltirib chiqaradi, bu esa bizni eski usullarga olib keladi.
Kod almashishning eski usullari (va nima uchun ular samarasiz)
Tarixan, jamoalar turli frontend ilovalari o'rtasida kod almashish uchun bir nechta usullarni sinab ko'rishgan, ularning har biri mikro-frontend kontekstida jiddiy kamchiliklarga ega.
NPM Paketlari
Eng keng tarqalgan yondashuv — bu umumiy komponentlar yoki utilitalarni versiyalangan NPM paketi sifatida nashr etish. Umumiy komponentlar kutubxonasi klassik misoldir.
- Muammo: Bu yig'ish vaqtidagi (build-time) bog'liqlikdir. Agar A jamoasi `my-ui-library` dagi umumiy `Button` komponentini 1.1 versiyasidan 1.2 ga yangilasa, B va C jamoalari o'zlarining `package.json` faylini qo'lda yangilamaguncha, `npm install` ni ishga tushirmaguncha va butun mikro-frontendini qayta joylashtirmaguncha bu yangilanishni olmaydilar. Bu qattiq bog'liqlikni yaratadi va mustaqil joylashtirishlar maqsadiga zid keladi. Bu shuningdek, brauzerda bir xil komponentning bir nechta versiyalari yuklanishiga olib keladi, bu esa yakuniy to'plamni shishiradi.
Umumiy ish maydonlariga ega Monorepolar
Monorepolar (Lerna yoki Yarn/NPM ish maydonlari kabi vositalardan foydalanib) barcha mikro-frontendlarni bitta repozitoriyda saqlaydi. Bu umumiy paketlarni boshqarishni osonlashtiradi.
- Muammo: Monorepolar dasturchi tajribasiga yordam bersa-da, ular asosiy ish vaqti (runtime) muammosini hal qilmaydi. Siz hali ham yig'ish vaqtidagi bog'liqliklarga tayanib qolasiz. Umumiy kutubxonaga kiritilgan o'zgartirish hali ham o'zgarishni aks ettirish uchun barcha iste'molchi ilovalarni qayta qurishni va qayta joylashtirishni talab qiladi.
`<script>` Teglari orqali tashqi skriptlar
jQuery yoki React kabi kutubxonalarni CDN'dan `<script>` tegi orqali kiritishning eski usuli.
- Muammo: Bu yondashuv mo'rt va to'g'ri bog'liqliklarni boshqarish tizimiga ega emas. U global `window` obyektini ifloslantiradi, bu esa potentsial ziddiyatlarga olib keladi. Versiyalarni boshqarish qo'lda va xatolarga moyil bo'lib, tree-shaking yo'q, ya'ni siz undan faqat bitta kichik funksiyani ishlatsangiz ham butun kutubxonani yuklaysiz.
Bu usullarning barchasi bitta fundamental kamchilikka ega: ular ilovalarni yig'ish vaqtida bog'laydi. Module Federation bu zanjirni ish vaqti bog'liqliklarini yaratish orqali uzadi.
Module Federation-ga kirish: Paradigma o'zgarishi
Module Federation JavaScript ilovasiga ish vaqtida boshqa, butunlay alohida ilovadan kodni dinamik ravishda yuklash imkonini beradi. Aslini olganda, u mustaqil ravishda joylashtirilgan ilovalarga foydalanuvchi brauzerida yagona, yaxlit ilova kabi ishlashiga imkon beradi.
Buni API kabi tasavvur qiling, lekin frontend komponentlari uchun. Bitta ilova komponentni "taqdim etishi" mumkin, boshqa ilova esa uni o'zining `package.json` faylida to'g'ridan-to'g'ri bog'liqlik sifatida saqlamasdan "iste'mol qilishi" mumkin. Bog'lanish jonli ravishda, brauzerda, foydalanuvchiga kerak bo'lganda amalga oshiriladi.
Bu shuni anglatadiki, agar To'lov jamoasi o'zining `MiniCart` komponentini yangilab, uni joylashtirsa, headerda `MiniCart`ni ko'rsatadigan asosiy Shell ilovasi keyingi sahifa yangilanishida yangi versiyani avtomatik ravishda yuklaydi—Shell ilovasini qayta qurish yoki qayta joylashtirish shart bo'lmasdan. Bu o'yinni o'zgartiruvchi holatdir.
Module Federation-ning asosiy tushunchalari
Bu qanday ishlashini tushunish uchun biz Webpack konfiguratsiyasida belgilangan ba'zi asosiy terminologiya bilan tanishishimiz kerak.
Host (Mezbon)
Host — bu ish vaqtida boshqa ilovalardan modullarni iste'mol qiladigan Webpack buildidir. Odatda, bu sizning asosiy ilova qobig'ingiz — foydalanuvchi birinchi yuklaydigan ilova. Host, shuningdek, o'z modullarini ham taqdim etishi mumkin va ko'pincha shunday qiladi.
Remote (Masofaviy)
Remote — bu boshqa ilovalar tomonidan iste'mol qilinishi uchun modullarni taqdim etadigan Webpack buildidir. Mahsulot mikro-frontendi o'zining `ProductPage` komponentini taqdim etadigan Remote hisoblanadi.
Muhim: Bitta ilova bir vaqtning o'zida ham Host, ham Remote bo'lishi mumkin.
Taqdim etilgan modullar (Exposed Modules)
Bular Remote tomonidan Hostlarning iste'mol qilishi uchun taqdim etilgan maxsus fayllardir (`.js`, `.jsx`, `.ts` va hokazo). Bu aniq bir shartnoma; faqat siz `exposes` konfiguratsiyasida ro'yxatga olgan modullarni import qilish mumkin.
Umumiy modullar (Shared Modules)
Bu yerda bog'liqliklarni dedublikatsiya qilish (takrorlanishni oldini olish) sehri sodir bo'ladi. Ushbu konfiguratsiya bir nechta, mustaqil ravishda qurilgan ilovalarga bitta kutubxonaning yagona nusxasini almashish imkonini beradi. Masalan, agar Host ham, Remote ham React-dan foydalansa, siz uni `shared` modul sifatida sozlashingiz mumkin. Ish vaqtida Module Federation aqlli ravishda React-ning mos keluvchi versiyasi allaqachon yuklanganligini tekshiradi. Agar shunday bo'lsa, remote o'zining nusxasini yuklab olish o'rniga Host-ning nusxasidan foydalanadi, bu esa freymvorkning ikki marta yuklanishini oldini oladi.
Webpack Konfiguratsiyasi Misoli
Keling, ushbu atamalarni amalda ko'rish uchun kontseptual `webpack.config.js` faylini ko'rib chiqaylik.
Remote ilova uchun (masalan, `productApp`):
// productApp-ning webpack.config.js faylida
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
// ... boshqa webpack sozlamalari
plugins: [
new ModuleFederationPlugin({
name: 'productApp', // Ushbu remote uchun unikal nom
filename: 'remoteEntry.js', // Host yuklab oladigan manifest fayli
exposes: {
'./ProductPage': './src/ProductPage',
},
shared: { react: { singleton: true }, 'react-dom': { singleton: true } },
}),
],
};
Host ilova uchun (masalan, `shellApp`):
// shellApp-ning webpack.config.js faylida
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
// ... boshqa webpack sozlamalari
plugins: [
new ModuleFederationPlugin({
name: 'shellApp',
remotes: {
productApp: 'productApp@http://localhost:3001/remoteEntry.js',
},
shared: { react: { singleton: true }, 'react-dom': { singleton: true } },
}),
],
};
Ish vaqtida modul almashish aslida qanday ishlaydi: Bosqichma-bosqich tahlil
Keling, federatsiyalangan modulning serverdan foydalanuvchi ekranigacha bo'lgan yo'lini kuzatib chiqaylik.
- Host Yuklanadi: Foydalanuvchi `www.ecommerce.com` ga kiradi, bu `shellApp`ni yuklaydi. Brauzer uning dastlabki HTML va JavaScript to'plamlarini yuklab oladi.
- `remoteEntry.js` Fayli: `shellApp` dagi `ModuleFederationPlugin` konfiguratsiyasi unga `productApp` haqida ma'lumot beradi. O'zining ishga tushirish jarayonining bir qismi sifatida Host belgilangan URL manzilidan (`http://localhost:3001/remoteEntry.js`) `remoteEntry.js` faylini oladi. Bu fayl juda kichik bo'lib, manifest yoki qidiruv jadvali vazifasini bajaradi va Host-ga `productApp` qaysi modullarni taqdim etishi va ularni qanday olish kerakligini aytadi.
- Dinamik Importni Ishga Tushirish: `shellApp` kodining ichida mahsulot sahifasini yuklash uchun dinamik import mavjud, ehtimol `React.lazy` yordamida:
const ProductPage = React.lazy(() => import('productApp/ProductPage'));
- Ish Vaqtida Modulni Aniqlash: Webpack-ning ish vaqti (runtime) bu `import()` chaqiruvini ushlab qoladi. U `productApp`ni federatsiyalangan remote sifatida taniydi. U `ProductPage` modulini o'z ichiga olgan maxsus JavaScript chunkini topish uchun allaqachon yuklab olingan `remoteEntry.js` manifestiga murojaat qiladi.
- Komponent Chunkini Olish: Keyin runtime `productApp` serveridan o'sha maxsus chunkni (masalan, `_src_ProductPage_js.js`) olish uchun tarmoq so'rovini amalga oshiradi.
- Aqlli Bog'liqlik Almashinuvi: Bu eng muhim qism. `ProductPage` kodini ishga tushirishdan oldin, runtime uning bog'liqliklarini tekshiradi. `ProductPage`ga React kerak. `shared` konfiguratsiyasi runtime-ga Host-ning doirasida React-ning singleton nusxasi mavjudligini tekshirishni aytadi. `shellApp` allaqachon React-ni yuklaganligi sababli, runtime shunchaki `ProductPage`ga o'sha mavjud nusxaga havola beradi. React qayta yuklanmaydi. Keyin `ProductPage` ishga tushiriladi va ekranda render qilinadi.
Ish vaqtida almashishning asosiy afzalliklari qayta ko'rib chiqildi
Mexanizmni tushunish afzalliklarni yaqqol ko'rsatadi.
Haqiqiy Mustaqil Joylashtirishlar
`productApp` jamoasi xatolikni tuzatishi, yangi xususiyat qo'shishi va o'z serverini joylashtirishi mumkin. Foydalanuvchi keyingi safar `shellApp`ga tashrif buyurib, mahsulot sahifasiga o'tganida, ular yangi, yangilangan komponent kodini oladilar. `shellApp` jamoasi hech narsa qilmadi. Bu ajratishning (decoupling) eng yuqori shaklidir.
To'plam Hajmining Keskin Kamayishi
Module Federation bo'lmasa, agar beshta turli mikro-frontendning barchasi React va Material-UI kabi komponentlar kutubxonasidan foydalansa, foydalanuvchi bu ulkan kutubxonalarni besh marta yuklab olishi mumkin. `shared` modul konfiguratsiyasi bilan ular faqat bir marta yuklanadi. Bu, ayniqsa, murakkab ilovalar uchun ishlash samaradorligining sezilarli darajada yaxshilanishiga va sahifaning tezroq yuklanishiga olib keladi.
Jamoa Avtonomiyasi va Masshtablashuvchanlikning Oshishi
Jamoalar haqiqatan ham o'zlarining domeniga ma'lumotlar bazasidan tortib UI gacha egalik qilishlari mumkin. Ushbu tashkiliy masshtablash kompaniyalarga monolitik rivojlanishga xos bo'lgan aloqa va muvofiqlashtirish xarajatlarisiz o'zlarining muhandislik jamoalarini kengaytirish imkonini beradi.
Chidamlilik va Zaxira variantlari (Fallbacks)
Agar remote ilova ishlamay qolsa nima bo'ladi? Modullar dinamik ravishda yuklanganligi sababli, siz bu xatoliklarni o'z kodingizda bemalol boshqarishingiz mumkin. React-ning `ErrorBoundary` komponenti kabi vositalardan foydalanib, siz modul yuklanishidagi xatolikni ushlab, butun ilovani ishdan chiqarish o'rniga zaxira UI ni (masalan, "Mahsulot xizmati hozirda mavjud emas. Iltimos, keyinroq qayta urinib ko'ring.") ko'rsatishingiz mumkin.
Bosqichma-bosqich Modernizatsiya
Module Federation eski monolitdan voz kechish uchun kuchli vositadir. Mavjud monolitni Host sifatida sozlash mumkin. Yangi xususiyatlar alohida, zamonaviy mikro-frontendlar (Remotes) sifatida yaratilishi mumkin. Keyin Host ushbu yangi xususiyatlarni dinamik ravishda import qilib, render qilishi mumkin, bu esa yuqori xavfli, "katta portlash" bilan qayta yozishni talab qilmasdan eski kod bazasini asta-sekin siqib chiqaradi.
Federatsiyalangan Dunyodagi Qiyinchiliklar va Mulohazalar
Module Federation nihoyatda kuchli, ammo bu har qanday muammoning yechimi emas. Ushbu arxitekturani qabul qilish bir nechta qiyinchiliklarni diqqat bilan ko'rib chiqishni talab qiladi.
Umumiy Ilova Holati (State)
Agar headerdagi `MiniCart` (`checkoutApp`dan) foydalanuvchi `ProductPage`da (`productApp`dan) "Savatga qo'shish" tugmasini bosganda yangilanishi kerak bo'lsa, ular qanday aloqa qiladi? Bu klassik mikro-frontend muammosidir.
- Yechimlar: Umumiy yondashuvlar brauzer hodisalaridan (masalan, Custom Events) foydalanish, `window.localStorage` yoki `sessionStorage`dan foydalanish, Host-dan umumiy holatni boshqarish kutubxonasini (kichik Redux yoki Zustand do'koni kabi) taqdim etish yoki ota-ilovadan qayta chaqiruvlar (callbacks) va ma'lumotlarni uzatishni o'z ichiga oladi. Asosiy narsa - aloqa shartnomasini iloji boricha sodda va barqaror saqlashdir.
Versiyalash va Buzuvchi O'zgarishlar
Agar `productApp` jamoasi o'zining `ProductPage` komponenti uchun propslarni o'zgartirsa-chi? Ular bu o'zgarishni joylashtirishi mumkin va to'satdan `shellApp` (eski propslarni uzatadigan) ishdan chiqadi. Module Federation-ning `shared` konfiguratsiyasida bog'liqlik versiyalari nomuvofiqligini boshqarish imkoniyatlari mavjud (masalan, ma'lum bir versiyani talab qilish), ammo taqdim etilgan modulning shartnomasini o'zi jamoaviy muloqot va API versiyalash strategiyalari orqali boshqarilishi kerak.
Asboblar va Dasturlash Tajribasi
Mahalliy ishlab chiqish muhiti murakkabroq bo'lishi mumkin. `shellApp` ustida ishlayotgan dasturchi to'liq tajribani ko'rish uchun `productApp` va `checkoutApp`ni mahalliy ravishda ishga tushirishi kerak bo'lishi mumkin. Buni Docker Compose yoki maxsus skriptlar kabi vositalar bilan boshqarish mumkin, ammo bu dastlabki bosqichda dasturchi operatsiyalariga (developer operations) sarmoya kiritishni talab qiladi.
Global Uslublar va Foydalanuvchi Tajribasining Izchilligi
`productApp`dagi tugma `checkoutApp`dagi tugma bilan bir xil ko'rinishini qanday ta'minlaysiz? Izchil dizayn tizimini saqlash juda muhim. Strategiyalar quyidagilarni o'z ichiga oladi:
- Har bir mikro-frontendda sozlangan umumiy CSS utilita kutubxonasi (masalan, Tailwind CSS).
- Umumiy UI mikro-frontendidan umumiy `ThemeProvider` komponentini taqdim etish.
- Izchil mavzuni (ranglar, shriftlar, oraliqlar) ta'minlash uchun Host tomonidan ildiz darajasida belgilangan CSS Custom Properties (o'zgaruvchilar) dan foydalanish.
Xulosa: Kelajak Federatsiyalashgandir
Module Federation frontend arxitekturasida fundamental sakrashni anglatadi. U ish vaqtida kod almashish uchun mustahkam, nativ brauzer yechimini taqdim etish orqali keng ko'lamli, taqsimlangan veb-ilovalarni yaratishning asosiy muammolarini bevosita hal qiladi.
Bog'liqliklarni yig'ish vaqtidan ish vaqtiga o'tkazish orqali u haqiqiy mustaqil joylashtirishlarga yo'l ochadi, sotuvchining kodini takrorlanishini bartaraf etish orqali ishlash samaradorligini oshiradi va jamoalarga avtonom ishlash imkoniyatini beradi. Garchi u holatni boshqarish va interfeys shartnomalari atrofida yangi murakkabliklarni keltirib chiqarsa-da, katta, uzoq muddatli ilovalar uchun uning afzalliklari shubhasizdir.
Tashkilotlar o'zlarining raqamli mahsulotlari va muhandislik jamoalarini kengaytirishda davom etar ekan, ajratish, avtonomiya va samaradorlikni rag'batlantiradigan arxitekturalar standartga aylanadi. Module Federation endi tor doiradagi yoki eksperimental texnologiya emas; u keyingi avlod chidamli, masshtablanuvchan va qo'llab-quvvatlanadigan mikro-frontend ilovalarini yaratish uchun asosiy ustundir.