Wat zijn modules?

Met modules verdeel je JavaScript-code over meerdere bestanden. Elk bestand is een module die bepaalde functies, variabelen of classes exporteert. Andere bestanden kunnen die importeren.

Waarom modules?
  • Overzicht — elke module heeft één verantwoordelijkheid
  • Herbruikbaar — importeer dezelfde code in meerdere bestanden
  • Onderhoudbaar — aanpassen op één plek werkt overal
  • Standaard — alle moderne frameworks (React, Vue) gebruiken modules

Zonder modules

<!-- Alle code in één groot bestand -->
<script src="alles.js"></script>

Met modules

<!-- Code verdeeld over logische bestanden -->
<script type="module" src="app.js"></script>
// app.js importeert wat het nodig heeft
import { berekenBtw } from './utils.js';
import { toonGebruiker } from './ui.js';

export

Met export maak je code beschikbaar voor andere bestanden.

// utils.js

export function berekenBtw(prijs) {
  return prijs * 1.21;
}

export function afronden(getal, decimalen = 2) {
  return Number(getal.toFixed(decimalen));
}

export const BTW_PERCENTAGE = 0.21;
Je kunt export direct voor een functie, variabele of class zetten. Die worden dan named exports.

Export onderaan het bestand

// utils.js — alternatief: exporteer alles onderaan
function berekenBtw(prijs) {
  return prijs * 1.21;
}

function afronden(getal, decimalen = 2) {
  return Number(getal.toFixed(decimalen));
}

const BTW_PERCENTAGE = 0.21;

export { berekenBtw, afronden, BTW_PERCENTAGE };

import

Met import haal je exports op uit een ander bestand.

// app.js
import { berekenBtw, afronden } from './utils.js';

const prijs = 100;
const prijsMetBtw = berekenBtw(prijs);
console.log(afronden(prijsMetBtw)); // 121
  • De namen tussen { } moeten exact overeenkomen met de export-namen
  • Het pad begint met ./ (zelfde map) of ../ (map omhoog)
  • De extensie .js is verplicht in de browser

Alles importeren met *

import * as utils from './utils.js';

console.log(utils.berekenBtw(100)); // 121
console.log(utils.BTW_PERCENTAGE);  // 0.21
Importeer bij voorkeur alleen wat je nodig hebt. * as importeert alles — ook wat je niet gebruikt.

Default export

Een bestand kan één default export hebben. Dit is de hoofdexport van het bestand, vaak een klasse of de belangrijkste functie.

// gebruiker.js
export default function maakGebruiker(naam, email) {
  return {
    naam,
    email,
    aangemeldOp: new Date()
  };
}
// app.js — importeer default export (geen accolades)
import maakGebruiker from './gebruiker.js';

const gebruiker = maakGebruiker('Jan', 'jan@email.com');
console.log(gebruiker.naam); // "Jan"
Bij een default import mag je zelf de naam kiezen — je hoeft niet dezelfde naam te gebruiken als in de export.
import createUser from './gebruiker.js'; // andere naam, werkt ook

Default + named exports combineren

// api.js
export default async function fetchData(url) {
  const response = await fetch(url);
  return response.json();
}

export const BASE_URL = 'https://api.example.com';
export function buildUrl(endpoint) {
  return `${BASE_URL}/${endpoint}`;
}
// app.js
import fetchData, { BASE_URL, buildUrl } from './api.js';

const url = buildUrl('gebruikers');
const data = await fetchData(url);

Named vs default exports

Named export Default export
Meerdere per bestand Maximaal één per bestand
Naam moet overeenkomen bij import Naam vrij te kiezen bij import
export function naam export default function
import { naam } from '...' import naam from '...'
Handig voor utility functies Handig voor de hoofdexport van een bestand

Alias met as

Met as geef je een import of export een andere naam.

Import alias

import { berekenBtw as calculateTax } from './utils.js';

console.log(calculateTax(100)); // 121

Naamconflicten oplossen

import { formatDatum as formatNl } from './nl-utils.js';
import { formatDatum as formatEn } from './en-utils.js';

console.log(formatNl(new Date())); // "24-3-2026"
console.log(formatEn(new Date())); // "3/24/2026"

Modules in HTML

Om modules te gebruiken in de browser voeg je type="module" toe aan je script-tag.

<!-- Zonder type="module" werkt import/export niet -->
<script src="app.js"></script>

<!-- Met type="module" -->
<script type="module" src="app.js"></script>
Wat verandert er met type="module"?
  • import en export werken
  • Code heeft automatisch strict mode
  • Code wordt uitgesteld tot de HTML klaar is (zoals defer)
  • Elke module heeft zijn eigen scope — geen globale variabelen
Modules werken niet bij het direct openen van een HTML-bestand (file://). Je hebt een lokale server nodig, zoals de Live Server extensie in VS Code.

Praktische bestandsstructuur

Een veelgebruikte indeling voor een kleine JavaScript-app:

project/
├── index.html
├── js/
│   ├── app.js          // hoofdbestand, importeert alles
│   ├── api.js          // fetch-functies
│   ├── ui.js           // DOM-manipulatie functies
│   └── utils.js        // hulpfuncties (berekeningen, formattering)

Voorbeeld — utils.js

// js/utils.js
export function formateerPrijs(prijs) {
  return `€${prijs.toFixed(2)}`;
}

export function datumNaarString(datum) {
  return datum.toLocaleDateString('nl-NL');
}

export const MAX_ITEMS = 100;

Voorbeeld — ui.js

// js/ui.js
export function toonFoutmelding(tekst) {
  const el = document.querySelector('#fout');
  el.textContent = tekst;
  el.style.display = 'block';
}

export function verbergFoutmelding() {
  document.querySelector('#fout').style.display = 'none';
}

export function toonLaadSpinner() {
  document.querySelector('#spinner').style.display = 'block';
}

export function verbergLaadSpinner() {
  document.querySelector('#spinner').style.display = 'none';
}

Voorbeeld — app.js

// js/app.js
import { formateerPrijs } from './utils.js';
import { toonFoutmelding, toonLaadSpinner, verbergLaadSpinner } from './ui.js';

async function laadProducten() {
  toonLaadSpinner();

  try {
    const response = await fetch('./data/producten.json');
    const producten = await response.json();

    const html = producten
      .map(p => `
  • ${p.naam} — ${formateerPrijs(p.prijs)}
  • `) .join(''); document.querySelector('#producten').innerHTML = html; } catch (error) { toonFoutmelding('Producten konden niet worden geladen'); } finally { verbergLaadSpinner(); } } laadProducten();

    Samenvatting

    Syntax Beschrijving
    export function naam Named export van een functie
    export { a, b } Meerdere named exports onderaan
    export default Hoofd-export van een bestand
    import { a } from './bestand.js' Named import
    import naam from './bestand.js' Default import
    import * as utils from './bestand.js' Alles importeren als object
    import { a as b } Import met alias