Norsk

Frigjør kraften i mikro-frontender med JavaScript Module Federation i Webpack 5. Lær hvordan du bygger skalerbare, vedlikeholdbare og uavhengige webapplikasjoner.

JavaScript Module Federation med Webpack 5: En Omfattende Guide til Mikro-frontender

I det stadig utviklende landskapet for webutvikling, kan det være en formidabel oppgave å bygge store og komplekse applikasjoner. Tradisjonelle monolittiske arkitekturer fører ofte til økt utviklingstid, flaskehalser ved utrulling og utfordringer med å opprettholde kodekvalitet. Mikro-frontender har dukket opp som et kraftig arkitekturmønster for å møte disse utfordringene, og lar team bygge og rulle ut uavhengige deler av en større webapplikasjon. En av de mest lovende teknologiene for å implementere mikro-frontender er JavaScript Module Federation, introdusert i Webpack 5.

Hva er Mikro-frontender?

Mikro-frontender er en arkitektonisk stil der en frontend-applikasjon deles opp i mindre, uavhengige enheter, som kan utvikles, testes og rulles ut autonomt av forskjellige team. Hver mikro-frontend er ansvarlig for et spesifikt forretningsdomene eller en funksjon, og de settes sammen under kjøring for å danne det komplette brukergrensesnittet.

Tenk på det som et selskap: i stedet for å ha ett gigantisk utviklingsteam, har du flere mindre team som fokuserer på spesifikke områder. Hvert team kan jobbe uavhengig, noe som gir raskere utviklingssykluser og enklere vedlikehold. Se for deg en stor e-handelsplattform som Amazon; forskjellige team kan håndtere produktkatalogen, handlekurven, utsjekkingsprosessen og brukerkontoadministrasjon. Disse kunne alle vært uavhengige mikro-frontender.

Fordeler med Mikro-frontender:

Utfordringer med Mikro-frontender:

Hva er JavaScript Module Federation?

JavaScript Module Federation er en funksjon i Webpack 5 som lar deg dele kode mellom separat kompilerte JavaScript-applikasjoner under kjøring. Det gjør det mulig å eksponere deler av applikasjonen din som "moduler" som kan konsumeres av andre applikasjoner, uten å måtte publisere til et sentralt register som npm.

Tenk på Module Federation som en måte å skape et føderert økosystem av applikasjoner, der hver applikasjon kan bidra med sin egen funksjonalitet og konsumere funksjonalitet fra andre applikasjoner. Dette eliminerer behovet for avhengigheter ved byggetid og muliggjør virkelig uavhengige utrullinger.

For eksempel kan et designsystem-team eksponere UI-komponenter som moduler, og forskjellige applikasjonsteam kan konsumere disse komponentene direkte fra designsystem-applikasjonen, uten å måtte installere dem som npm-pakker. Når designsystem-teamet oppdaterer komponentene, reflekteres endringene automatisk i alle konsumerende applikasjoner.

Nøkkelkonsepter i Module Federation:

Sette opp Module Federation med Webpack 5: En Praktisk Guide

La oss gå gjennom et praktisk eksempel på å sette opp Module Federation med Webpack 5. Vi vil lage to enkle applikasjoner: en Host-applikasjon (vert) og en Remote-applikasjon (fjern). Remote-applikasjonen vil eksponere en komponent, og Host-applikasjonen vil konsumere den.

1. Prosjektoppsett

Opprett to separate mapper for applikasjonene dine: `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. Konfigurasjon av Remote-applikasjonen

I `remote`-mappen, opprett 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'], }, }; ```

Opprett `public/index.html` med grunnleggende HTML-struktur. Det viktige er `

`

3. Konfigurasjon av Host-applikasjonen

I `host`-mappen, opprett følgende filer:

  • `src/index.js`: Inngangspunkt for applikasjonen.
  • `webpack.config.js`: Webpack-konfigurasjonsfil.

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

Opprett `public/index.html` med grunnleggende HTML-struktur (lignende som remote-appen). Det viktige er `

`

4. Installer Babel

I både `host`- og `remote`-mappene, installer Babel-avhengigheter:

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

5. Kjør Applikasjonene

I både `host`- og `remote`-mappene, legg til følgende skript i `package.json`:

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

Start nå begge applikasjonene:

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

Åpne nettleseren din og naviger til `http://localhost:3000`. Du bør se Host-applikasjonen med Remote-komponentet rendret inne i den.

Forklaring av Viktige Konfigurasjonsalternativer:

Avanserte Teknikker i Module Federation

Module Federation tilbyr mange avanserte funksjoner som kan hjelpe deg med å bygge enda mer sofistikerte mikro-frontend-arkitekturer.

Dynamiske Remotes

I stedet for å hardkode URL-ene til fjernapplikasjoner i Webpack-konfigurasjonen, kan du laste dem dynamisk under kjøring. Dette lar deg enkelt oppdatere plasseringen til fjernapplikasjoner uten å måtte bygge vertsapplikasjonen på nytt.

For eksempel kan du lagre URL-ene til fjernapplikasjoner i en konfigurasjonsfil eller en database og laste dem dynamisk ved hjelp av JavaScript.

```javascript // In webpack.config.js remotes: { remote: `promise new Promise(resolve => { const urlParams = new URLSearchParams(window.location.search); const remoteUrl = urlParams.get('remote'); // Anta at remoteUrl er noe som 'http://localhost:3001/remoteEntry.js' const script = document.createElement('script'); script.src = remoteUrl; script.onload = () => { // nøkkelen i module federation er at fjernappen er // tilgjengelig via navnet i fjernkonfigurasjonen resolve(window.remote); }; document.head.appendChild(script); })`, }, ```

Nå kan du laste vertappen med en query-parameter `?remote=http://localhost:3001/remoteEntry.js`

Versjonerte Delte Moduler

Module Federation kan automatisk håndtere versjonering og deduplisering av delte moduler for å sikre at bare én kompatibel versjon av hver modul lastes. Dette er spesielt viktig når man håndterer store og komplekse applikasjoner med mange avhengigheter.

Du kan spesifisere versjonsområdet for hver delte modul i Webpack-konfigurasjonen.

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

Egendefinerte Modullastere

Module Federation lar deg definere egendefinerte modullastere som kan brukes til å laste moduler fra forskjellige kilder eller i forskjellige formater. Dette kan være nyttig for å laste moduler fra en CDN eller fra et egendefinert modulregister.

Dele Tilstand mellom Mikro-frontender

En av utfordringene med mikro-frontend-arkitekturer er å dele tilstand mellom forskjellige mikro-frontender. Det er flere tilnærminger du kan ta for å løse denne utfordringen:

Beste Praksis for Implementering av Mikro-frontender med Module Federation

Her er noen beste praksiser å ha i bakhodet når du implementerer mikro-frontender med Module Federation:

Eksempler fra den Virkelige Verden på Module Federation i Praksis

Selv om spesifikke casestudier ofte er konfidensielle, er her noen generaliserte scenarioer der Module Federation kan være utrolig nyttig:

Konklusjon

JavaScript Module Federation i Webpack 5 gir en kraftig og fleksibel måte å bygge mikro-frontend-arkitekturer på. Det lar deg dele kode mellom separat kompilerte JavaScript-applikasjoner under kjøring, noe som muliggjør uavhengige utrullinger, teknologisk mangfold og forbedret teamautonomi. Ved å følge beste praksis beskrevet i denne guiden, kan du utnytte Module Federation til å bygge skalerbare, vedlikeholdbare og innovative webapplikasjoner.

Fremtiden for frontend-utvikling lener seg utvilsomt mot modulære og distribuerte arkitekturer. Module Federation gir et avgjørende verktøy for å bygge disse moderne systemene, og gjør det mulig for team å lage komplekse applikasjoner med større hastighet, fleksibilitet og robusthet. Etter hvert som teknologien modnes, kan vi forvente å se enda flere innovative bruksområder og beste praksiser dukke opp.