Nederlands

Ontgrendel de kracht van micro-frontends met JavaScript Module Federation in Webpack 5. Leer hoe u schaalbare, onderhoudbare en onafhankelijke webapplicaties bouwt.

JavaScript Module Federation met Webpack 5: Een Uitgebreide Gids voor Micro-frontends

In het steeds evoluerende landschap van webontwikkeling kan het bouwen van grote en complexe applicaties een enorme opgave zijn. Traditionele monolithische architecturen leiden vaak tot langere ontwikkeltijden, knelpunten bij de implementatie en uitdagingen bij het handhaven van de codekwaliteit. Micro-frontends zijn naar voren gekomen als een krachtig architectonisch patroon om deze uitdagingen aan te gaan, waardoor teams onafhankelijke onderdelen van een grotere webapplicatie kunnen bouwen en implementeren. Een van de meest veelbelovende technologieën voor het implementeren van micro-frontends is JavaScript Module Federation, geïntroduceerd in Webpack 5.

Wat zijn Micro-frontends?

Micro-frontends zijn een architecturale stijl waarbij een frontend-app wordt opgesplitst in kleinere, onafhankelijke eenheden, die autonoom door verschillende teams kunnen worden ontwikkeld, getest en geïmplementeerd. Elke micro-frontend is verantwoordelijk voor een specifiek bedrijfsdomein of een specifieke functie, en ze worden tijdens runtime samengesteld om de volledige gebruikersinterface te vormen.

Zie het als een bedrijf: in plaats van één gigantisch ontwikkelteam, heb je meerdere kleinere teams die zich op specifieke gebieden richten. Elk team kan onafhankelijk werken, wat zorgt voor snellere ontwikkelingscycli en eenvoudiger onderhoud. Denk aan een groot e-commerceplatform zoals Amazon; verschillende teams kunnen de productcatalogus, het winkelwagentje, het afrekenproces en het beheer van gebruikersaccounts beheren. Dit zouden allemaal onafhankelijke micro-frontends kunnen zijn.

Voordelen van Micro-frontends:

Uitdagingen van Micro-frontends:

Wat is JavaScript Module Federation?

JavaScript Module Federation is een functie van Webpack 5 waarmee u code kunt delen tussen afzonderlijk gecompileerde JavaScript-applicaties tijdens runtime. Het stelt u in staat delen van uw applicatie bloot te stellen als "modules" die door andere applicaties kunnen worden gebruikt, zonder dat u deze hoeft te publiceren naar een centrale repository zoals npm.

Zie Module Federation als een manier om een gefedereerd ecosysteem van applicaties te creëren, waarbij elke applicatie zijn eigen functionaliteit kan bijdragen en functionaliteit van andere applicaties kan gebruiken. Dit elimineert de noodzaak voor build-time afhankelijkheden en maakt echt onafhankelijke implementaties mogelijk.

Een design system team kan bijvoorbeeld UI-componenten als modules beschikbaar stellen, en verschillende applicatieteams kunnen deze componenten rechtstreeks vanuit de design system applicatie gebruiken, zonder ze als npm-pakketten te hoeven installeren. Wanneer het design system team de componenten bijwerkt, worden de wijzigingen automatisch doorgevoerd in alle gebruikende applicaties.

Kernconcepten in Module Federation:

Module Federation opzetten met Webpack 5: Een Praktische Gids

Laten we een praktisch voorbeeld doorlopen van het opzetten van Module Federation met Webpack 5. We maken twee eenvoudige applicaties: een Host-applicatie en een Remote-applicatie. De Remote-applicatie zal een component beschikbaar stellen, en de Host-applicatie zal deze gebruiken.

1. Projectopzet

Maak twee afzonderlijke mappen voor uw applicaties: `host` en `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. Configuratie van de Remote Applicatie

Maak in de `remote`-map de volgende bestanden aan:

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 = () => (

Dit is een Remote Component!

Gerenderd vanuit de Remote Applicatie.

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

Maak `public/index.html` met een basis HTML-structuur. Belangrijk is `

`

3. Configuratie van de Host Applicatie

Maak in de `host`-map de volgende bestanden aan:

  • `src/index.js`: Toegangspunt voor de applicatie.
  • `webpack.config.js`: Webpack-configuratiebestand.

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 Applicatie

Remote Component laden...
}>
); 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'], }, }; ```

Maak `public/index.html` met een basis HTML-structuur (vergelijkbaar met de remote-app). Belangrijk is `

`

4. Babel installeren

Installeer in zowel de `host`- als de `remote`-map de Babel-afhankelijkheden:

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

5. De Applicaties Uitvoeren

Voeg in zowel de `host`- als de `remote`-map het volgende script toe aan `package.json`:

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

Start nu beide applicaties:

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

Open uw browser en navigeer naar `http://localhost:3000`. U zou de Host-applicatie moeten zien met het Remote Component erin gerenderd.

Uitleg van Belangrijke Configuratieopties:

Geavanceerde Module Federation Technieken

Module Federation biedt veel geavanceerde functies die u kunnen helpen nog geavanceerdere micro-frontendarchitecturen te bouwen.

Dynamische Remotes

In plaats van de URL's van remote-applicaties hard te coderen in de Webpack-configuratie, kunt u ze dynamisch tijdens runtime laden. Dit stelt u in staat om de locatie van remote-applicaties eenvoudig bij te werken zonder de host-applicatie opnieuw te hoeven bouwen.

U kunt bijvoorbeeld de URL's van remote-applicaties opslaan in een configuratiebestand of een database en ze dynamisch laden met JavaScript.

```javascript // In webpack.config.js remotes: { remote: `promise new Promise(resolve => { const urlParams = new URLSearchParams(window.location.search); const remoteUrl = urlParams.get('remote'); // Ga ervan uit dat remoteUrl zoiets is als 'http://localhost:3001/remoteEntry.js' const script = document.createElement('script'); script.src = remoteUrl; script.onload = () => { // de sleutel van module federation is dat de remote-app is // beschikbaar is onder de naam die in de remote is gedefinieerd resolve(window.remote); }; document.head.appendChild(script); })`, }, ```

Nu kunt u de host-app laden met een queryparameter `?remote=http://localhost:3001/remoteEntry.js`

Gedeelde Modules met Versiebeheer

Module Federation kan automatisch het versiebeheer en de ontdubbeling van gedeelde modules afhandelen om ervoor te zorgen dat er slechts één compatibele versie van elke module wordt geladen. Dit is vooral belangrijk bij grote en complexe applicaties met veel afhankelijkheden.

U kunt het versiebereik van elke gedeelde module specificeren in de Webpack-configuratie.

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

Aangepaste Module Loaders

Module Federation stelt u in staat om aangepaste module loaders te definiëren die kunnen worden gebruikt om modules uit verschillende bronnen of in verschillende formaten te laden. Dit kan handig zijn voor het laden van modules vanaf een CDN of een aangepast module register.

Status Delen tussen Micro-frontends

Een van de uitdagingen van micro-frontendarchitecturen is het delen van de status (state) tussen verschillende micro-frontends. Er zijn verschillende benaderingen die u kunt volgen om deze uitdaging aan te gaan:

Best Practices voor het Implementeren van Micro-frontends met Module Federation

Hier zijn enkele best practices om in gedachten te houden bij het implementeren van micro-frontends met Module Federation:

Praktijkvoorbeelden van Module Federation in Actie

Hoewel specifieke casestudies vaak vertrouwelijk zijn, zijn hier enkele algemene scenario's waarin Module Federation ongelooflijk nuttig kan zijn:

Conclusie

JavaScript Module Federation in Webpack 5 biedt een krachtige en flexibele manier om micro-frontendarchitecturen te bouwen. Het stelt u in staat om code te delen tussen afzonderlijk gecompileerde JavaScript-applicaties tijdens runtime, wat onafhankelijke implementaties, technologische diversiteit en verbeterde teamautonomie mogelijk maakt. Door de best practices in deze gids te volgen, kunt u Module Federation benutten om schaalbare, onderhoudbare en innovatieve webapplicaties te bouwen.

De toekomst van frontend-ontwikkeling neigt ongetwijfeld naar modulaire en gedistribueerde architecturen. Module Federation biedt een cruciaal hulpmiddel voor het bouwen van deze moderne systemen, waardoor teams complexe applicaties kunnen creëren met meer snelheid, flexibiliteit en veerkracht. Naarmate de technologie volwassener wordt, kunnen we verwachten dat er nog meer innovatieve gebruiksscenario's en best practices zullen ontstaan.