Ota mikro-frontendien teho käyttöön JavaScript Module Federationin ja Webpack 5:n avulla. Opi rakentamaan skaalautuvia, ylläpidettäviä ja itsenäisiä verkkosovelluksia.
JavaScript Module Federation ja Webpack 5: Kattava opas mikro-frontend-arkkitehtuuriin
Jatkuvasti kehittyvässä web-kehityksen maailmassa suurten ja monimutkaisten sovellusten rakentaminen voi olla haastavaa. Perinteiset monoliittiset arkkitehtuurit johtavat usein pidempiin kehitysaikoihin, julkaisujen pullonkauloihin ja haasteisiin koodin laadun ylläpidossa. Mikro-frontendit ovat nousseet voimakkaaksi arkkitehtuurimalliksi vastaamaan näihin haasteisiin, mahdollistaen tiimeille suuremman verkkosovelluksen itsenäisten osien rakentamisen ja julkaisemisen. Yksi lupaavimmista teknologioista mikro-frontendien toteuttamiseen on JavaScript Module Federation, joka esiteltiin Webpack 5:ssä.
Mitä ovat mikro-frontendit?
Mikro-frontendit ovat arkkitehtuurityyli, jossa frontend-sovellus jaetaan pienempiin, itsenäisiin yksiköihin, joita eri tiimit voivat kehittää, testata ja julkaista itsenäisesti. Jokainen mikro-frontend vastaa tietystä liiketoiminta-alueesta tai ominaisuudesta, ja ne kootaan yhteen ajon aikana muodostamaan täydellinen käyttöliittymä.
Ajattele sitä kuin yritystä: sen sijaan, että olisi yksi jättimäinen kehitystiimi, on useita pienempiä tiimejä, jotka keskittyvät tiettyihin osa-alueisiin. Jokainen tiimi voi työskennellä itsenäisesti, mikä mahdollistaa nopeammat kehityssyklit ja helpomman ylläpidon. Esimerkiksi suuressa verkkokaupassa, kuten Amazonissa, eri tiimit saattavat hallita tuotekatalogia, ostoskoria, kassaprosessia ja käyttäjätilien hallintaa. Nämä kaikki voisivat olla itsenäisiä mikro-frontend-sovelluksia.
Mikro-frontendien edut:
- Itsenäiset julkaisut: Tiimit voivat julkaista mikro-frontend-sovelluksensa itsenäisesti vaikuttamatta sovelluksen muihin osiin. Tämä vähentää julkaisuriskiä ja mahdollistaa nopeammat julkaisusyklit.
- Teknologiariippumattomuus: Eri mikro-frontend-sovelluksia voidaan rakentaa eri teknologioilla tai kehyksillä (esim. React, Angular, Vue.js). Tämä antaa tiimeille vapauden valita paras teknologia omiin tarpeisiinsa ja ottaa asteittain käyttöön uusia teknologioita ilman koko sovelluksen uudelleenkirjoittamista. Kuvittele, että yksi tiimi käyttää Reactia tuotekatalogiin, toinen Vue.js:ää markkinoinnin aloitussivuihin ja kolmas Angularia kassaprosessiin.
- Parempi tiimien autonomia: Tiimeillä on täysi omistajuus omista mikro-frontend-sovelluksistaan, mikä johtaa lisääntyneeseen autonomiaan, nopeampaan päätöksentekoon ja parempaan kehittäjien tuottavuuteen.
- Lisääntynyt skaalautuvuus: Mikro-frontendit mahdollistavat sovelluksen horisontaalisen skaalautumisen julkaisemalla yksittäisiä mikro-frontend-sovelluksia eri palvelimille.
- Koodin uudelleenkäytettävyys: Jaettuja komponentteja ja kirjastoja voidaan helposti jakaa mikro-frontendien välillä.
- Helpompi ylläpitää: Pienemmät koodikannat ovat yleensä helpompia ymmärtää, ylläpitää ja debugata.
Mikro-frontendien haasteet:
- Lisääntynyt monimutkaisuus: Useiden mikro-frontendien hallinta voi lisätä kokonaisarkkitehtuurin monimutkaisuutta, erityisesti kommunikaation, tilanhallinnan ja julkaisun osalta.
- Suorituskyvyn kuormitus: Useiden mikro-frontendien lataaminen voi aiheuttaa suorituskykyyn liittyvää kuormitusta, varsinkin jos niitä ei ole optimoitu kunnolla.
- Poikkileikkaavat huolenaiheet: Poikkileikkaavien huolenaiheiden, kuten autentikoinnin, auktorisoinnin ja teemoituksen, käsittely voi olla haastavaa mikro-frontend-arkkitehtuurissa.
- Operatiivinen kuormitus: Vaatii kypsiä DevOps-käytäntöjä ja infrastruktuuria useiden mikro-frontendien julkaisun ja valvonnan hallintaan.
Mikä on JavaScript Module Federation?
JavaScript Module Federation on Webpack 5:n ominaisuus, joka mahdollistaa koodin jakamisen erikseen käännettyjen JavaScript-sovellusten välillä ajon aikana. Se antaa sinun paljastaa osia sovelluksestasi "moduuleina", joita muut sovellukset voivat käyttää ilman tarvetta julkaista niitä keskitettyyn pakettivarastoon, kuten npm:ään.
Ajattele Module Federationia tapana luoda federoitu sovellusten ekosysteemi, jossa jokainen sovellus voi tarjota omaa toiminnallisuuttaan ja käyttää muiden sovellusten toiminnallisuutta. Tämä poistaa tarpeen käännösaikaisille riippuvuuksille ja mahdollistaa todella itsenäiset julkaisut.
Esimerkiksi design system -tiimi voi paljastaa käyttöliittymäkomponentteja moduuleina, ja eri sovellustiimit voivat käyttää näitä komponentteja suoraan design system -sovelluksesta ilman tarvetta asentaa niitä npm-paketteina. Kun design system -tiimi päivittää komponentteja, muutokset heijastuvat automaattisesti kaikkiin niitä käyttäviin sovelluksiin.
Module Federationin keskeiset käsitteet:
- Host (Isäntä): Pääsovellus, joka käyttää etämoduuleja.
- Remote (Etäsovellus): Sovellus, joka paljastaa moduuleja muiden sovellusten käytettäväksi.
- Shared Modules (Jaetut moduulit): Moduulit, jotka jaetaan isännän ja etäsovellusten välillä (esim. React, Lodash). Module Federation voi automaattisesti käsitellä jaettujen moduulien versiointia ja duplikaattien poistoa varmistaakseen, että kustakin moduulista ladataan vain yksi versio.
- Exposed Modules (Paljastetut moduulit): Tietyt etäsovelluksen moduulit, jotka asetetaan muiden sovellusten saataville.
- RemoteEntry.js: Webpackin generoima tiedosto, joka sisältää metatiedot etäsovelluksen paljastetuista moduuleista. Isäntäsovellus käyttää tätä tiedostoa löytääkseen ja ladatakseen etämoduulit.
Module Federationin käyttöönotto Webpack 5:llä: Käytännön opas
Käydään läpi käytännön esimerkki Module Federationin käyttöönotosta Webpack 5:llä. Luomme kaksi yksinkertaista sovellusta: Host-sovelluksen (isäntä) ja Remote-sovelluksen (etä). Remote-sovellus paljastaa komponentin, ja Host-sovellus käyttää sitä.
1. Projektin alustus
Luo kaksi erillistä kansiota sovelluksillesi: `host` ja `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. Etäsovelluksen (Remote) konfigurointi
`remote`-kansiossa luo seuraavat tiedostot:
- `src/index.js`: Sovelluksen aloituspiste.
- `src/RemoteComponent.jsx`: Komponentti, joka paljastetaan.
- `webpack.config.js`: Webpack-konfiguraatiotiedosto.
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'], }, }; ```Luo `public/index.html` perus-HTML-rakenteella. Tärkeää on `
`3. Isäntäsovelluksen (Host) konfigurointi
`host`-kansiossa luo seuraavat tiedostot:
- `src/index.js`: Sovelluksen aloituspiste.
- `webpack.config.js`: Webpack-konfiguraatiotiedosto.
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'], }, }; ```Luo `public/index.html` perus-HTML-rakenteella (kuten etäsovelluksessa). Tärkeää on `
`4. Asenna Babel
Asenna Babel-riippuvuudet sekä `host`- että `remote`-kansioihin:
```bash npm install --save-dev @babel/core @babel/preset-env @babel/preset-react babel-loader ```5. Käynnistä sovellukset
Lisää seuraava skripti `package.json`-tiedostoon sekä `host`- että `remote`-kansioissa:
```json "scripts": { "start": "webpack serve" } ```Käynnistä nyt molemmat sovellukset:
```bash cd remote npm start cd ../host npm start ```Avaa selaimesi ja siirry osoitteeseen `http://localhost:3000`. Sinun pitäisi nähdä isäntäsovellus, jonka sisällä etäkomponentti on renderöity.
Tärkeimpien konfigurointivaihtoehtojen selitys:
- `name`: Ainutlaatuinen nimi sovellukselle.
- `filename`: Sen tiedoston nimi, joka sisältää metatiedot paljastetuista moduuleista (esim. `remoteEntry.js`).
- `exposes`: Kartoitus moduulien nimistä tiedostopolkuihin, määritellen mitkä moduulit tulisi paljastaa.
- `remotes`: Kartoitus etäsovellusten nimistä URL-osoitteisiin, määritellen mistä kunkin etäsovelluksen remoteEntry.js-tiedosto löytyy.
- `shared`: Lista moduuleista, jotka tulisi jakaa isännän ja etäsovellusten välillä. `singleton: true` -asetus varmistaa, että kustakin jaetusta moduulista ladataan vain yksi instanssi. `eager: true` -asetus varmistaa, että jaettu moduuli ladataan innokkaasti (eli ennen muita moduuleja).
Edistyneet Module Federation -tekniikat
Module Federation tarjoaa monia edistyneitä ominaisuuksia, jotka auttavat rakentamaan entistäkin kehittyneempiä mikro-frontend-arkkitehtuureja.
Dynaamiset etäsovellukset (Dynamic Remotes)
Sen sijaan, että kovakoodaisit etäsovellusten URL-osoitteet Webpack-konfiguraatioon, voit ladata ne dynaamisesti ajon aikana. Tämä mahdollistaa etäsovellusten sijainnin helpon päivittämisen ilman isäntäsovelluksen uudelleenrakentamista.
Voit esimerkiksi tallentaa etäsovellusten URL-osoitteet konfiguraatiotiedostoon tai tietokantaan ja ladata ne dynaamisesti JavaScriptillä.
```javascript // webpack.config.js:ssä remotes: { remote: `promise new Promise(resolve => { const urlParams = new URLSearchParams(window.location.search); const remoteUrl = urlParams.get('remote'); // Oletetaan, että remoteUrl on jotain kuten 'http://localhost:3001/remoteEntry.js' const script = document.createElement('script'); script.src = remoteUrl; script.onload = () => { // module federationin ydin on, että etäsovellus on // saatavilla etäsovelluksen nimellä resolve(window.remote); }; document.head.appendChild(script); })`, }, ```Nyt voit ladata isäntäsovelluksen kyselyparametrilla `?remote=http://localhost:3001/remoteEntry.js`
Versioidut jaetut moduulit
Module Federation voi automaattisesti käsitellä jaettujen moduulien versiointia ja duplikaattien poistoa varmistaakseen, että kustakin moduulista ladataan vain yksi yhteensopiva versio. Tämä on erityisen tärkeää suurissa ja monimutkaisissa sovelluksissa, joilla on monia riippuvuuksia.
Voit määrittää kunkin jaetun moduulin versioalueen Webpack-konfiguraatiossa.
```javascript // webpack.config.js:ssä shared: { react: { singleton: true, eager: true, requiredVersion: '^18.0.0' }, 'react-dom': { singleton: true, eager: true, requiredVersion: '^18.0.0' }, }, ```Mukautetut moduulilataajat
Module Federation antaa sinun määritellä mukautettuja moduulilataajia, joita voidaan käyttää moduulien lataamiseen eri lähteistä tai eri muodoissa. Tämä voi olla hyödyllistä moduulien lataamisessa CDN:stä tai mukautetusta moduulirekisteristä.
Tilan jakaminen mikro-frontendien välillä
Yksi mikro-frontend-arkkitehtuurien haasteista on tilan jakaminen eri mikro-frontendien välillä. Tähän haasteeseen on useita lähestymistapoja:
- URL-pohjainen tilanhallinta: Tallenna tila URL-osoitteeseen ja käytä URL-osoitetta kommunikointiin mikro-frontendien välillä. Tämä on yksinkertainen ja suoraviivainen lähestymistapa, mutta se voi muuttua kömpelöksi monimutkaisen tilan kanssa.
- Mukautetut tapahtumat (Custom events): Käytä mukautettuja tapahtumia tilanmuutosten lähettämiseen mikro-frontendien välillä. Tämä mahdollistaa löyhän kytkennän mikro-frontendien välillä, mutta tapahtumatilausten hallinta voi olla vaikeaa.
- Jaettu tilanhallintakirjasto: Käytä jaettua tilanhallintakirjastoa, kuten Reduxia tai MobX:ää, koko sovelluksen tilan hallintaan. Tämä tarjoaa keskitetyn ja johdonmukaisen tavan hallita tilaa, mutta se voi tuoda riippuvuuden tiettyyn tilanhallintakirjastoon.
- Viestinvälittäjä (Message Broker): Käytä viestinvälittäjää, kuten RabbitMQ:ta tai Kafkaa, helpottamaan kommunikaatiota ja tilan jakamista mikro-frontendien välillä. Tämä on monimutkaisempi ratkaisu, mutta se tarjoaa korkean asteen joustavuutta ja skaalautuvuutta.
Parhaat käytännöt mikro-frontendien toteuttamiseen Module Federationilla
Tässä on joitakin parhaita käytäntöjä, jotka kannattaa pitää mielessä, kun toteutat mikro-frontend-sovelluksia Module Federationilla:
- Määritä selkeät rajat jokaiselle mikro-frontendille: Jokaisen mikro-frontendin tulisi vastata tietystä liiketoiminta-alueesta tai ominaisuudesta, ja sillä tulisi olla hyvin määritellyt rajapinnat.
- Käytä johdonmukaista teknologiakokonaisuutta: Vaikka Module Federation antaa sinun käyttää eri teknologioita eri mikro-frontend-sovelluksissa, on yleensä hyvä idea käyttää johdonmukaista teknologiakokonaisuutta monimutkaisuuden vähentämiseksi ja ylläpidettävyyden parantamiseksi.
- Luo selkeät viestintäprotokollat: Määritä selkeät viestintäprotokollat sille, miten mikro-frontendit ovat vuorovaikutuksessa keskenään.
- Automatisoi julkaisuprosessi: Automatisoi julkaisuprosessi varmistaaksesi, että mikro-frontendit voidaan julkaista itsenäisesti ja luotettavasti. Harkitse CI/CD-putkien ja infrastructure-as-code-työkalujen käyttöä.
- Valvo mikro-frontendiesi suorituskykyä: Valvo mikro-frontendiesi suorituskykyä tunnistaaksesi ja korjataksesi mahdolliset suorituskyvyn pullonkaulat. Käytä työkaluja, kuten Google Analytics, New Relic tai Datadog.
- Toteuta vankka virheidenkäsittely: Toteuta vankka virheidenkäsittely varmistaaksesi, että sovelluksesi on vikasietoinen.
- Omaksu hajautettu hallintomalli: Valtuuta tiimit tekemään päätöksiä omista mikro-frontend-sovelluksistaan säilyttäen samalla yleisen johdonmukaisuuden ja laadun.
Tosielämän esimerkkejä Module Federationista toiminnassa
Vaikka tietyt tapaustutkimukset ovat usein luottamuksellisia, tässä on joitain yleistettyjä skenaarioita, joissa Module Federation voi olla erittäin hyödyllinen:
- Verkkokauppa-alustat: Kuten aiemmin mainittiin, suuret verkkokauppa-alustat voivat käyttää Module Federationia rakentaakseen itsenäisiä mikro-frontend-sovelluksia tuotekatalogille, ostoskorille, kassaprosessille ja käyttäjätilien hallinnalle. Tämä mahdollistaa eri tiimien työskentelyn näiden ominaisuuksien parissa itsenäisesti ja niiden julkaisemisen vaikuttamatta sovelluksen muihin osiin. Globaali alusta voisi mukauttaa ominaisuuksia eri alueille etämoduulien avulla.
- Finanssipalvelusovellukset: Finanssipalvelusovelluksilla on usein monimutkaisia käyttöliittymiä, joissa on monia eri ominaisuuksia. Module Federationia voidaan käyttää rakentamaan itsenäisiä mikro-frontend-sovelluksia eri tilityypeille, kaupankäyntialustoille ja raportointinäkymille. Tietyille maille ominaiset vaatimustenmukaisuusominaisuudet voidaan toimittaa Module Federationin kautta.
- Terveydenhuollon portaalit: Terveydenhuollon portaalit voivat käyttää Module Federationia rakentaakseen itsenäisiä mikro-frontend-sovelluksia potilashallintaan, ajanvaraukseen ja potilastietojen käyttöön. Eri moduuleja eri vakuutusyhtiöille tai alueille voidaan ladata dynaamisesti.
- Sisällönhallintajärjestelmät (CMS): CMS voi käyttää Module Federationia antaakseen käyttäjille mahdollisuuden lisätä mukautettua toiminnallisuutta verkkosivustoilleen lataamalla etämoduuleja kolmansien osapuolien kehittäjiltä. Eri teemoja, lisäosia ja widgettejä voidaan jakaa itsenäisinä mikro-frontend-sovelluksina.
- Oppimisen hallintajärjestelmät (LMS): LMS voi tarjota itsenäisesti kehitettyjä kursseja, jotka on integroitu yhtenäiseen alustaan Module Federationin kautta. Yksittäisten kurssien päivitykset eivät vaadi koko alustan uudelleenjulkaisua.
Yhteenveto
JavaScript Module Federation Webpack 5:ssä tarjoaa tehokkaan ja joustavan tavan rakentaa mikro-frontend-arkkitehtuureja. Se mahdollistaa koodin jakamisen erikseen käännettyjen JavaScript-sovellusten välillä ajon aikana, mikä mahdollistaa itsenäiset julkaisut, teknologisen monimuotoisuuden ja parannetun tiimien autonomian. Noudattamalla tässä oppaassa esitettyjä parhaita käytäntöjä voit hyödyntää Module Federationia rakentaaksesi skaalautuvia, ylläpidettäviä ja innovatiivisia verkkosovelluksia.
Frontend-kehityksen tulevaisuus on epäilemättä suuntautumassa modulaarisiin ja hajautettuihin arkkitehtuureihin. Module Federation tarjoaa ratkaisevan tärkeän työkalun näiden nykyaikaisten järjestelmien rakentamiseen, mahdollistaen tiimeille monimutkaisten sovellusten luomisen suuremmalla nopeudella, joustavuudella ja kestävyydellä. Teknologian kypsyessä voimme odottaa näkevämme entistäkin innovatiivisempia käyttötapauksia ja parhaita käytäntöjä.