Dansk

Frigør potentialet i micro-frontends med JavaScript Module Federation i Webpack 5. Lær hvordan du bygger skalerbare, vedligeholdelsesvenlige og uafhængige webapplikationer.

JavaScript Module Federation med Webpack 5: En Omfattende Guide til Micro-frontends

I det konstant udviklende landskab inden for webudvikling kan det være en skræmmende opgave at bygge store og komplekse applikationer. Traditionelle monolitiske arkitekturer fører ofte til øget udviklingstid, flaskehalse ved udrulning og udfordringer med at opretholde kodekvaliteten. Micro-frontends er opstået som et stærkt arkitektonisk mønster til at imødegå disse udfordringer, hvilket giver teams mulighed for at bygge og udrulle uafhængige dele af en større webapplikation. En af de mest lovende teknologier til implementering af micro-frontends er JavaScript Module Federation, introduceret i Webpack 5.

Hvad er Micro-frontends?

Micro-frontends er en arkitektonisk stil, hvor en frontend-applikation opdeles i mindre, uafhængige enheder, som kan udvikles, testes og udrulles autonomt af forskellige teams. Hver micro-frontend er ansvarlig for et specifikt forretningsdomæne eller en funktion, og de sammensættes ved kørsel for at danne den komplette brugergrænseflade.

Tænk på det som en virksomhed: i stedet for at have ét gigantisk udviklingsteam, har du flere mindre teams, der fokuserer på specifikke områder. Hvert team kan arbejde uafhængigt, hvilket giver hurtigere udviklingscyklusser og lettere vedligeholdelse. Overvej en stor e-handelsplatform som Amazon; forskellige teams kunne administrere produktkataloget, indkøbskurven, betalingsprocessen og brugerkontoadministration. Disse kunne alle være uafhængige micro-frontends.

Fordele ved Micro-frontends:

Udfordringer ved Micro-frontends:

Hvad er JavaScript Module Federation?

JavaScript Module Federation er en funktion i Webpack 5, der giver dig mulighed for at dele kode mellem separat kompilerede JavaScript-applikationer ved kørsel. Det gør det muligt for dig at eksponere dele af din applikation som "moduler", der kan forbruges af andre applikationer, uden at skulle publicere dem til et centralt repository som npm.

Tænk på Module Federation som en måde at skabe et fødereret økosystem af applikationer, hvor hver applikation kan bidrage med sin egen funktionalitet og forbruge funktionalitet fra andre applikationer. Dette eliminerer behovet for afhængigheder på byggetidspunktet og giver mulighed for ægte uafhængige deployments.

For eksempel kan et designsystem-team eksponere UI-komponenter som moduler, og forskellige applikationsteams kan forbruge disse komponenter direkte fra designsystem-applikationen, uden at skulle installere dem som npm-pakker. Når designsystem-teamet opdaterer komponenterne, afspejles ændringerne automatisk i alle forbrugende applikationer.

Nøglekoncepter i Module Federation:

Opsætning af Module Federation med Webpack 5: En Praktisk Guide

Lad os gennemgå et praktisk eksempel på, hvordan man opsætter Module Federation med Webpack 5. Vi vil oprette to simple applikationer: en Host-applikation og en Remote-applikation. Remote-applikationen vil eksponere en komponent, og Host-applikationen vil forbruge den.

1. Projektopsætning

Opret to separate mapper til dine applikationer: `host` og `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 af Remote-applikationen

I `remote`-mappen skal du oprette følgende 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'], }, }; ```

Opret `public/index.html` med grundlæggende HTML-struktur. Det vigtige er `

`

3. Konfiguration af Host-applikationen

I `host`-mappen skal du oprette følgende filer:

  • `src/index.js`: Applikationens indgangspunkt.
  • `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'], }, }; ```

Opret `public/index.html` med grundlæggende HTML-struktur (svarende til remote-appen). Det vigtige er `

`

4. Installer Babel

I både `host`- og `remote`-mapperne skal du installere Babel-afhængigheder:

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

5. Kør applikationerne

I både `host`- og `remote`-mapperne skal du tilføje følgende script til `package.json`:

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

Start nu begge applikationer:

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

Åbn din browser og gå til `http://localhost:3000`. Du bør se Host-applikationen med Remote-komponenten gengivet inde i den.

Forklaring af Nøglekonfigurationsmuligheder:

Avancerede Module Federation-teknikker

Module Federation tilbyder mange avancerede funktioner, der kan hjælpe dig med at bygge endnu mere sofistikerede micro-frontend-arkitekturer.

Dynamiske Remotes

I stedet for at hardcode URL'erne for remote-applikationer i Webpack-konfigurationen, kan du indlæse dem dynamisk ved kørsel. Dette giver dig mulighed for let at opdatere placeringen af remote-applikationer uden at skulle genbygge host-applikationen.

For eksempel kan du gemme URL'erne for remote-applikationer i en konfigurationsfil eller en database og indlæse dem dynamisk ved hjælp af JavaScript.

```javascript // In webpack.config.js remotes: { remote: `promise new Promise(resolve => { const urlParams = new URLSearchParams(window.location.search); const remoteUrl = urlParams.get('remote'); // Assume remoteUrl is something like 'http://localhost:3001/remoteEntry.js' const script = document.createElement('script'); script.src = remoteUrl; script.onload = () => { // the key of module federation is that the remote app is // available using the name in the remote resolve(window.remote); }; document.head.appendChild(script); })`, }, ```

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

Versionerede Delte Moduler

Module Federation kan automatisk håndtere versionering og deduplikering af delte moduler for at sikre, at kun én kompatibel version af hvert modul indlæses. Dette er især vigtigt, når man arbejder med store og komplekse applikationer med mange afhængigheder.

Du kan specificere versionsområdet for hvert delt modul i Webpack-konfigurationen.

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

Brugerdefinerede Modul-Loaders

Module Federation giver dig mulighed for at definere brugerdefinerede modul-loaders, der kan bruges til at indlæse moduler fra forskellige kilder eller i forskellige formater. Dette kan være nyttigt til at indlæse moduler fra en CDN eller fra et brugerdefineret modul-register.

Deling af State mellem Micro-frontends

En af udfordringerne ved micro-frontend-arkitekturer er at dele state mellem forskellige micro-frontends. Der er flere tilgange, du kan anvende for at løse denne udfordring:

Bedste Praksis for Implementering af Micro-frontends med Module Federation

Her er nogle bedste praksisser, du skal huske på, når du implementerer micro-frontends med Module Federation:

Eksempler fra den Virkelige Verden på Module Federation i Praksis

Selvom specifikke casestudier ofte er fortrolige, er her nogle generelle scenarier, hvor Module Federation kan være utroligt nyttigt:

Konklusion

JavaScript Module Federation i Webpack 5 giver en kraftfuld og fleksibel måde at bygge micro-frontend-arkitekturer på. Det giver dig mulighed for at dele kode mellem separat kompilerede JavaScript-applikationer ved kørsel, hvilket muliggør uafhængige deployments, teknologisk diversitet og forbedret team-autonomi. Ved at følge de bedste praksisser, der er beskrevet i denne guide, kan du udnytte Module Federation til at bygge skalerbare, vedligeholdelsesvenlige og innovative webapplikationer.

Fremtiden for frontend-udvikling hælder utvivlsomt mod modulære og distribuerede arkitekturer. Module Federation udgør et afgørende værktøj til at bygge disse moderne systemer, hvilket gør det muligt for teams at skabe komplekse applikationer med større hastighed, fleksibilitet og modstandsdygtighed. Efterhånden som teknologien modnes, kan vi forvente at se endnu flere innovative anvendelsestilfælde og bedste praksisser dukke op.