Bundler — een bouwhulpmiddel dat meerdere JavaScript-modules combineert in een of meer bestanden voor gebruik in een browser of mobiele app. Moderne bundelaars (Webpack, Metro, Vite) lijmen niet alleen bestanden aan elkaar, maar voeren ook transpilatie, minificatie en optimalisatie van bronnen uit. Volgens Webpack Concepts (2026) vermindert een goede configuratie van de bundelaar de buildgrootte met 40–60% zonder functieverlies.
Belangrijkste punten
Bundler (modulebundelaar) — een commandoregelhulpmiddel dat een ingangspunt (entry point) — het hoofdbestand van de app — ontvangt en recursief al zijn afhankelijkheden doorloopt, waarbij een modulegraaf wordt gebouwd. Aan de uitgang genereert de bundelaar een of meer bestanden die kunnen worden gekoppeld aan een HTML-pagina of kunnen worden uitgevoerd in een mobiele app.
Browsers ondersteunden lange tijd geen modulair JavaScript-systeem op platformniveau. Bundler loste dit probleem op door honderden import en require om te zetten in één bestand. Tegenwoordig, zelfs met native ondersteuning voor ES-modules in browsers, voeren bundelaars extra taken uit: transpilatie van JSX en TypeScript, minificatie van code, code splitting voor lui laden en hot module replacement (HMR) voor versnelde ontwikkeling.
In mobiele ontwikkeling gebruikt React Native Metro als standaardbundelaar en Flutter zijn eigen op Dart gebaseerde buildsysteem. De keuze van de bundelaar heeft direct invloed op de ontwikkelsnelheid, app-grootte en runtime-prestaties.
Bundeling doorloopt verschillende fasen: parseren van invoerbestanden, bouwen van een afhankelijkheidsgraaf, transformeren van modules en genereren van uitvoerbestanden. In elke fase past de bundelaar loaders toe voor transformatie van broncode en plugins voor optimalisatie.
De bundelaar begint bij het ingangspunt, leest het bestand en bouwt een AST (abstracte syntaxisboom). Uit de AST worden alle import- en require-instructies gehaald. Voor elke gevonden import herhaalt de bundelaar het proces recursief totdat alle afhankelijkheden in één graaf zijn verzameld.
// Vereenvoudigde implementatie van een bundelaar
const fs = require('fs');
const path = require('path');
function buildGraph(entry) {
const content = fs.readFileSync(entry, 'utf-8');
const imports = content.match(/require\(['"](.+?)['"]\)/g);
const modulePath = path.resolve(path.dirname(entry), imports[0]);
return { entry, content, deps: [buildGraph(modulePath)] };
}
Na het bouwen van de graaf past de bundelaar loaders toe — transformaties die bestanden omzetten naar JavaScript: TypeScript → JS, SCSS → CSS, JSX → JSX-functies. Vervolgens voeren plugins extra transformaties uit: minificatie, inline-afbeeldingen, service worker-generatie.
Bundelaars zijn onderverdeeld in drie generaties: klassiek, gespecialiseerd en volgende generatie op basis van ES-modules. Elk type heeft zijn eigen architectuur en toepassingsgebied.
Webpack — de meest wijdverbreide bundelaar met een enorm ecosysteem. Het belangrijkste voordeel is flexibiliteit: duizenden loaders en plugins dekken vrijwel elk buildsjabloon. Parcel biedt een zero-config-benadering, waarbij automatisch de benodigde transformaties worden bepaald op basis van bestandsextensies. Beide bundelaars ondersteunen code splitting en HMR.
Metro is speciaal gemaakt voor React Native en werkt alleen met JavaScript en TypeScript. De architectuur is geoptimaliseerd voor mobiele ontwikkeling: ondersteuning voor inline requires, asynchroon laden van modules en integratie met Hermes engine. Rollup is gericht op bibliotheken en npm-pakketten en genereert schone ES-module-uitvoer zonder overbodige verpakking.
De keuze van de bundelaar hangt af van het platform en de projectvereisten. Webpack is universeel, maar vereist gedetailleerde configuratie. Metro is onmisbaar voor React Native. Vite biedt de snelste ontwikkeling dankzij native ES-modules.
| Kenmerk | Webpack | Metro | Vite |
|---|---|---|---|
| Platform | Web, universeel | React Native | Web, universeel |
| Snelheid dev-build | Gemiddeld | Hoog | Zeer hoog |
| Code splitting | Ja | Ja | Ja |
| HMR | Ja | Fast Refresh | Directe HMR |
| Pluginecosysteem | Enorm | Beperkt | Groeiend |
| Configuratie | Complex | Eenvoudig | Eenvoudig |
| TypeScript-ondersteuning | Via loaders | Ingebouwd | Ingebouwd |
Vite gebruikt esbuild voor pre-bundeling van afhankelijkheden en Rollup voor productiebuilds, wat een snelheidstoename van 5–10 keer oplevert in vergelijking met Webpack in ontwikkelmodus. Metro ondersteunt geen webdoelen, maar zorgt voor naadloze integratie met React Native bridge en Turbo Modules.
Configuratie van de bundelaar bepaalt hoe verschillende bestandstypen worden verwerkt, waar de build wordt gegenereerd en welke optimalisaties worden toegepast. Een typisch configuratiebestand bevat een ingangspunt, regels voor modules, plugins en uitvoerinstellingen.
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
clean: true,
},
module: {
rules: [
{
test: /\.(js|jsx|ts|tsx)$/,
exclude: /node_modules/,
use: { loader: 'babel-loader', options: { presets: ['@babel/preset-react'] } },
},
{ test: /\.css$/, use: ['style-loader', 'css-loader'] },
],
},
plugins: [new HtmlWebpackPlugin({ template: './public/index.html' })],
devServer: { port: 3000, hot: true },
};
Metro gebruikt aparte bestanden metro.config.js en babel.config.js voor configuratie. In tegenstelling tot Webpack is de configuratie van Metro veel eenvoudiger, omdat de bundelaar is gespecialiseerd voor React Native en geen configuratie van loaders voor stijlen of afbeeldingen vereist.
Zelfs ervaren ontwikkelaars krijgen te maken met bundelingsfouten. Duplicate module — een van de meest voorkomende problemen, wanneer dezelfde afhankelijkheid meerdere keren in de bundle terechtkomt vanwege versie-incompatibiliteit in package.json. Module not found treedt op wanneer het importpad onjuist is of het pakket niet is geïnstalleerd.
Metro is beperkt door bundelgroottes voor mobiele apparaten. Bij overschrijding van de limiet van 2–5 MB treedt de fout Unable to resolve module op vanwege onvoldoende geheugen op het apparaat. De oplossing — gebruik inline requires en RAM bundles voor lui laden van modules. Metro is ook gevoelig voor symlinks, dus voor monorepositories is extra configuratie van watchFolders in de configuratie vereist.
Voor Webpack is een typisch probleem Module parse failed, wanneer een bestand een onverwacht formaat heeft of de benodigde loader ontbreekt. Controle van de bestandsextensie en toevoeging van de juiste regel in module.rules lost het probleem op. Gebruik van source-map-explorer helpt bij het vinden van dubbele modules en overbodige afhankelijkheden in de uiteindelijke bundle.
Langzame build — een van de belangrijkste problemen bij het werken met bundelaars. Gebruik voor versnelling persistent caching, dat de resultaten van moduletransformaties tussen runs bewaart. Webpack 5 ondersteunt bestandscache via cache: { type: 'filesystem' }, Vite gebruikt esbuild voor pre-bundeling en Metro vertrouwt op modulecache in RAM. Stel bovendien exclude in voor node_modules in loaders om reeds gereed zijnde pakketten niet opnieuw te verwerken.
Code splitting — het splitsen van de bundle in delen die op verzoek worden geladen. Verschillende bundelaars implementeren deze strategie op hun eigen manier. Webpack ondersteunt dynamische import import(), die aparte delen voor elke module creëert. Metro gebruikt inline requires voor uitgesteld laden. Vite splitst automatisch vendor-delen en dynamische imports zonder extra configuratie. De keuze van de strategie hangt af van de projectvereisten: voor mobiele apps hebben kleinere initiële bundles met lui laden de voorkeur.
Voor een correcte werking van code splitting in React Native is extra configuratie vereist: Metro moet worden geconfigureerd voor het werken met asynchrone delen via inlineRequires. In Webpack en Vite werkt code splitting uit de doos bij gebruik van dynamische import()-syntaxis, die automatisch splitsingspunten creëert. Voor maximale efficiëntie combineert u code splitting met preload-hints via <link rel="preload"> voor kritieke delen.
Veelgestelde vragen
Voor eenvoudige projecten zonder JSX, TypeScript of CSS-modules kunt u rondkomen met native ES-modules in de browser. Voor productiebuilds zorgt de bundelaar echter voor minificatie, tree shaking en code splitting, die cruciaal zijn voor prestaties. Zonder bundelaar is het moeilijk om een modulaire architectuur in grote projecten te behouden.
Voor React Native — Metro (enige ondersteunde optie). Voor webapps — Vite voor nieuwe projecten (vanwege snelheid) of Webpack voor bestaande met een rijk ecosysteem. Voor bibliotheken en npm-pakketten — Rollup, omdat het schone ES-module-uitvoer genereert.
Bundler bepaalt direct de grootte van de uiteindelijke JS-bundle. Webpack met tree shaking kan de grootte met 30–50% verminderen. Metro voor React Native ondersteunt Hermes bytecode, die de grootte met 20–30% vermindert in vergelijking met gewoon JavaScript. Code splitting maakt het mogelijk modules op verzoek te laden, waardoor de initiële bundle kleiner wordt.
Voor het web genereert de bundelaar code die compatibel is met verschillende browsers en ondersteunt CSS, afbeeldingen en lettertypen. Voor mobiele platforms genereert Metro code voor de JavaScript-engine (Hermes of JSC), verwerkt geen CSS of HTML en optimaliseert de build voor de beperkte bronnen van het apparaat.
Ja, er bestaan projecten die Webpack gebruiken voor het webgedeelte en Metro voor React Native — bijvoorbeeld in monolithische repositories met een gedeelde codebase. Dit compliceert echter de CI/CD-configuratie en vereist synchronisatie van afhankelijkheidsversies. Het wordt aanbevolen om indien mogelijk één bundelaar voor alle doelen te gebruiken.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook