Svenska

Frigör kraften i mikro-frontends med JavaScript Module Federation i Webpack 5. Lär dig bygga skalbara, underhållbara och oberoende webbapplikationer.

JavaScript Module Federation med Webpack 5: En omfattande guide till mikro-frontends

I det ständigt föränderliga landskapet för webbutveckling kan det vara en skrämmande uppgift att bygga stora och komplexa applikationer. Traditionella monolitiska arkitekturer leder ofta till ökad utvecklingstid, flaskhalsar vid driftsättning och utmaningar med att upprätthålla kodkvaliteten. Mikro-frontends har framträtt som ett kraftfullt arkitektoniskt mönster för att hantera dessa utmaningar, vilket gör att team kan bygga och driftsätta oberoende delar av en större webbapplikation. En av de mest lovande teknologierna för att implementera mikro-frontends är JavaScript Module Federation, introducerad i Webpack 5.

Vad är mikro-frontends?

Mikro-frontends är en arkitektonisk stil där en frontend-applikation delas upp i mindre, oberoende enheter som kan utvecklas, testas och driftsättas autonomt av olika team. Varje mikro-frontend ansvarar för en specifik affärsdomän eller funktion, och de komponeras samman vid körtid för att bilda det kompletta användargränssnittet.

Tänk på det som ett företag: istället för att ha ett jättestort utvecklingsteam har du flera mindre team som fokuserar på specifika områden. Varje team kan arbeta självständigt, vilket möjliggör snabbare utvecklingscykler och enklare underhåll. Tänk på en stor e-handelsplattform som Amazon; olika team kan hantera produktkatalogen, varukorgen, kassaprocessen och användarkontohanteringen. Dessa skulle alla kunna vara oberoende mikro-frontends.

Fördelar med mikro-frontends:

Utmaningar med mikro-frontends:

Vad är JavaScript Module Federation?

JavaScript Module Federation är en funktion i Webpack 5 som låter dig dela kod mellan separat kompilerade JavaScript-applikationer vid körtid. Det gör det möjligt att exponera delar av din applikation som "moduler" som kan konsumeras av andra applikationer, utan att behöva publicera till ett centralt arkiv som npm.

Tänk på Module Federation som ett sätt att skapa ett federerat ekosystem av applikationer, där varje applikation kan bidra med sin egen funktionalitet och konsumera funktionalitet från andra applikationer. Detta eliminerar behovet av beroenden vid byggtid och möjliggör verkligt oberoende driftsättningar.

Till exempel kan ett team för ett designsystem exponera UI-komponenter som moduler, och olika applikationsteam kan konsumera dessa komponenter direkt från designsystemets applikation, utan att behöva installera dem som npm-paket. När designsystemteamet uppdaterar komponenterna, reflekteras ändringarna automatiskt i alla konsumerande applikationer.

Nyckelkoncept i Module Federation:

Konfigurera Module Federation med Webpack 5: En praktisk guide

Låt oss gå igenom ett praktiskt exempel på hur man konfigurerar Module Federation med Webpack 5. Vi skapar två enkla applikationer: en Host-applikation och en Remote-applikation. Remote-applikationen kommer att exponera en komponent, och Host-applikationen kommer att konsumera den.

1. Projektkonfiguration

Skapa två separata kataloger för dina applikationer: `host` och `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. Konfiguration av Remote-applikationen

I `remote`-katalogen, skapa följande filer:

src/index.js:

```javascript import React from 'react'; import ReactDOM from 'react-dom/client'; import RemoteComponent from './RemoteComponent'; const App = () => (

Remote Application

); const root = ReactDOM.createRoot(document.getElementById('root')); root.render(); ```

src/RemoteComponent.jsx:

```javascript import React from 'react'; const RemoteComponent = () => (

This is a Remote Component!

Rendered from the Remote Application.

); export default RemoteComponent; ```

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'], }, }; ```

Skapa `public/index.html` med grundläggande HTML-struktur. Det viktiga är `

`

3. Konfiguration av Host-applikationen

I `host`-katalogen, skapa följande filer:

  • `src/index.js`: Startpunkt för applikationen.
  • `webpack.config.js`: Webpack-konfigurationsfil.

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

Loading Remote Component...
}>
); const root = ReactDOM.createRoot(document.getElementById('root')); root.render(); ```

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'], }, }; ```

Skapa `public/index.html` med grundläggande HTML-struktur (liknande remote-appen). Det viktiga är `

`

4. Installera Babel

Installera Babel-beroenden i både `host`- och `remote`-katalogerna:

```bash npm install --save-dev @babel/core @babel/preset-env @babel/preset-react babel-loader ```

5. Kör applikationerna

Lägg till följande skript i `package.json` i både `host`- och `remote`-katalogerna:

```json "scripts": { "start": "webpack serve" } ```

Starta nu båda applikationerna:

```bash cd remote npm start cd ../host npm start ```

Öppna din webbläsare och navigera till `http://localhost:3000`. Du bör se Host-applikationen med Remote-komponenten renderad inuti den.

Förklaring av viktiga konfigurationsalternativ:

Avancerade tekniker med Module Federation

Module Federation erbjuder många avancerade funktioner som kan hjälpa dig att bygga ännu mer sofistikerade mikro-frontend-arkitekturer.

Dynamiska Remotes

Istället för att hårdkoda URL:erna till remote-applikationer i Webpack-konfigurationen kan du ladda dem dynamiskt vid körtid. Detta gör att du enkelt kan uppdatera platsen för remote-applikationer utan att behöva bygga om host-applikationen.

Du kan till exempel lagra URL:erna till remote-applikationer i en konfigurationsfil eller en databas och ladda dem dynamiskt med JavaScript.

```javascript // I webpack.config.js remotes: { remote: `promise new Promise(resolve => { const urlParams = new URLSearchParams(window.location.search); const remoteUrl = urlParams.get('remote'); // Anta att remoteUrl är något i stil med 'http://localhost:3001/remoteEntry.js' const script = document.createElement('script'); script.src = remoteUrl; script.onload = () => { // nyckeln till module federation är att remote-appen är // tillgänglig via namnet i remote-konfigurationen resolve(window.remote); }; document.head.appendChild(script); })`, }, ```

Nu kan du ladda host-appen med en query-parameter `?remote=http://localhost:3001/remoteEntry.js`

Versionerade delade moduler

Module Federation kan automatiskt hantera versionering och deduplicering av delade moduler för att säkerställa att endast en kompatibel version av varje modul laddas. Detta är särskilt viktigt när man hanterar stora och komplexa applikationer med många beroenden.

Du kan specificera versionsintervallet för varje delad modul i Webpack-konfigurationen.

```javascript // I webpack.config.js shared: { react: { singleton: true, eager: true, requiredVersion: '^18.0.0' }, 'react-dom': { singleton: true, eager: true, requiredVersion: '^18.0.0' }, }, ```

Anpassade modulladdare

Module Federation låter dig definiera anpassade modulladdare som kan användas för att ladda moduler från olika källor eller i olika format. Detta kan vara användbart för att ladda moduler från en CDN eller från ett anpassat modulregister.

Dela state mellan mikro-frontends

En av utmaningarna med mikro-frontend-arkitekturer är att dela state mellan olika mikro-frontends. Det finns flera tillvägagångssätt du kan använda för att hantera denna utmaning:

Bästa praxis för att implementera mikro-frontends med Module Federation

Här är några bästa praxis att tänka på när du implementerar mikro-frontends med Module Federation:

Verkliga exempel på Module Federation i praktiken

Även om specifika fallstudier ofta är konfidentiella, är här några generaliserade scenarier där Module Federation kan vara otroligt användbart:

Slutsats

JavaScript Module Federation i Webpack 5 erbjuder ett kraftfullt och flexibelt sätt att bygga mikro-frontend-arkitekturer. Det låter dig dela kod mellan separat kompilerade JavaScript-applikationer vid körtid, vilket möjliggör oberoende driftsättningar, teknisk mångfald och förbättrad teamautonomi. Genom att följa de bästa praxis som beskrivs i denna guide kan du utnyttja Module Federation för att bygga skalbara, underhållbara och innovativa webbapplikationer.

Framtiden för frontend-utveckling lutar utan tvekan mot modulära och distribuerade arkitekturer. Module Federation utgör ett avgörande verktyg för att bygga dessa moderna system, vilket gör det möjligt för team att skapa komplexa applikationer med större hastighet, flexibilitet och motståndskraft. Allt eftersom tekniken mognar kan vi förvänta oss att se ännu fler innovativa användningsfall och bästa praxis dyka upp.