✦ Oplossingen · Server- en developerfouten

ReferenceError: $ is not defined, require is not defined en meer

‘ReferenceError: $ is not defined’, ‘require is not defined’ of ‘Cannot access before initialization’? De oorzaak: laadvolgorde, scope of de verkeerde omgeving.

Zo ziet de foutmelding eruit

  • Uncaught ReferenceError: $ is not defined
  • Uncaught ReferenceError: jQuery is not defined
  • ReferenceError: require is not defined in ES module scope, you can use import instead
  • Uncaught ReferenceError: process is not defined
  • ReferenceError: document is not defined
  • ReferenceError: Cannot access 'config' before initialization

Waarom gebeurt dit?

Een ReferenceError betekent dat je code een naam gebruikt (een variabele, functie of object) die op dat moment en op die plek niet bestaat. Dat is iets anders dan een waarde die leeg is: bij Cannot read properties of undefined bestaat de variabele wel maar heeft hij geen waarde, hier kent JavaScript de naam helemaal niet.

In de browser is de oorzaak meestal de laadvolgorde: $ is not defined of jQuery is not defined betekent dat jouw script draait voordat jQuery is geladen, of dat jQuery helemaal niet laadt (verkeerd pad, geblokkeerd, 404). Andere oorzaken zijn scope, dus een variabele die binnen een functie of blok is gemaakt en daarbuiten wordt gebruikt, en een gewone tikfout (JavaScript is hoofdlettergevoelig).

Een tweede groep komt van de verkeerde omgeving. require en process bestaan in Node.js, niet in de browser; document en window bestaan in de browser, niet in Node.js. En in Node.js werkt require niet in een ES-module (een .mjs-bestand, of een project met "type": "module" in package.json). Een derde vorm is Cannot access 'x' before initialization: de variabele is met let, const of class gemaakt, maar je gebruikt hem al vóór de regel waarop hij wordt aangemaakt (de ‘temporal dead zone’).

Zo herken je dit probleem

  • De console toont ReferenceError met de naam erbij: ‘… is not defined’ of ‘Cannot access … before initialization’.
  • Bij $ of jQuery: kijk in het tabblad Network of het jQuery-bestand laadt; een 404 erop verklaart de fout (zie 404).
  • Krijg je ‘undefined (reading …)’, dan bestaat de variabele wel maar is hij leeg; dat is een andere fout.
  • Ontbreekt een bestand of module op schijf in Node.js, dan zie je eerder ‘Cannot find module’ of ENOENT.

Zo los je het op, stap voor stap

Menunamen kunnen per versie of toestel iets anders heten. Loop de stappen op volgorde af en stop zodra het werkt.

  1. Lees welke naam ontbreekt en waar

    Open de console (F12) en klik op het regelnummer achter de fout. Kijk welke naam niet bestaat en in welk bestand. Staat de fout in jouw script maar gaat het om iets uit een bibliotheek ($, jQuery, Chart, gtag), dan gaat het bijna altijd om laadvolgorde of een bibliotheek die niet laadt.

  2. Controleer of de bibliotheek laadt

    Kijk in het tabblad Network of het bestand van de bibliotheek wordt opgehaald met status 200. Een 404, een geblokkeerd verzoek door een adblocker of een fout in het pad betekent dat de naam nooit bestaat. Typ in de console de naam, bijvoorbeeld typeof jQuery; staat er "undefined", dan is hij niet geladen.

  3. Zet scripts in de juiste volgorde

    Een script dat jQuery gebruikt, moet ná jQuery komen. Gebruik je defer, zet het dan op beide scripts: scripts met defer worden in volgorde uitgevoerd. Met async is de volgorde niet gegarandeerd; gebruik dat niet voor scripts die van elkaar afhangen.

    <script src="/js/jquery.min.js" defer></script>
    <script src="/js/app.js" defer></script>
  4. Let op scope

    Een variabele die je met let of const binnen een functie, if of lus maakt, bestaat alleen daarbinnen. Maak hem in een hoger niveau aan als je hem ook daarbuiten nodig hebt. Gebruik je <script type="module">, dan zijn je variabelen niet meer globaal; een onclick="verstuur()" in de HTML vindt die functie dan niet. Koppel de klik in je script met addEventListener.

    // werkt niet buiten het blok:
    if (ok) { const melding = 'klaar'; }
    console.log(melding); // ReferenceError
    
    // wel:
    let melding = '';
    if (ok) { melding = 'klaar'; }
  5. Gebruik de juiste code voor de omgeving

    Krijg je require is not defined in de browser, dan is de code geschreven voor Node.js en moet hij door een bundelaar (zoals Vite of webpack), of je gebruikt import in een module. In Node.js met een ES-module gebruik je import in plaats van require. process is not defined in de browser komt vaak van process.env: veel bundelaars leveren omgevingsvariabelen op hun eigen manier aan, zoals import.meta.env bij Vite.

    // ES-module (Node.js of browser)
    import fs from 'node:fs';
    import { formatDatum } from './utils.js';
    
    // Vite: omgevingsvariabelen
    const api = import.meta.env.VITE_API_URL;
  6. document is not defined: draai browsercode in de browser

    Zie je document is not defined of window is not defined in Node.js, dan draait browsercode op de server, bijvoorbeeld bij server-side rendering of in een test. Voer zulke code pas uit in de browser, of controleer eerst of window bestaat.

    if (typeof window !== 'undefined') {
      document.querySelector('#app');
    }
  7. Cannot access before initialization: verplaats de declaratie

    Deze vorm betekent dat je een let, const of class gebruikt vóór de regel waar hij wordt gemaakt. Zet de declaratie hoger, of roep de functie die hem gebruikt pas later aan. In projecten met modules kan het ook een kringverwijzing zijn: twee bestanden die elkaar importeren, waarbij de ene de andere gebruikt voordat die klaar is met laden.

    // fout:
    console.log(config);
    const config = { taal: 'nl' };
    
    // goed:
    const config = { taal: 'nl' };
    console.log(config);

Let op: Laad jQuery of een andere bibliotheek niet twee keer om de fout op te lossen (bijvoorbeeld uit een thema én zelf). Een tweede kopie overschrijft de eerste, en plugins die op de eerste hingen, werken dan niet meer.

Wanneer schakel je hulp in?

  • De fout komt uit een thema, plugin of extern script en je weet niet welk bestand het laadt; bij WordPress zie ook kritieke fout.
  • Na het samenvoegen of verkleinen (minify) van scripts door een cacheplugin of bundelaar verschijnen ineens ReferenceErrors.
  • Een project moet over van require naar import en je wilt niets breken.
  • De fout treedt alleen live op en lokaal niet, en je vermoedt dat een bestand op de server ontbreekt.

Lukt het niet? Wij helpen

Kom je er met deze stappen niet uit, of wil je het liever niet zelf doen? We kijken online mee of komen langs. Hulp op afstand kost €20 per uur; komen we langs, dan is de prijs op aanvraag. Je weet vooraf waar je aan toe bent.

Aanvraag

Hulp aanvragen

Schrijf kort wat er misgaat en wat je al hebt geprobeerd. Kies of we bellen, online meekijken of langskomen.

Veelgestelde vragen

Vragen over dit probleem

Wat betekent ‘$ is not defined’?

Je script gebruikt jQuery voordat jQuery is geladen, of jQuery laadt helemaal niet. Laad jQuery eerder en controleer in het tabblad Network of het bestand gevonden wordt.

Waarom werkt require niet in de browser?

require hoort bij Node.js. In de browser gebruik je import in een module, of een bundelaar die de code geschikt maakt voor de browser.

Wat is het verschil tussen ‘is not defined’ en ‘undefined’?

Bij ‘is not defined’ bestaat de naam helemaal niet. Bij ‘undefined’ bestaat de variabele wel, maar heeft hij geen waarde.

Wat betekent ‘Cannot access before initialization’?

Je gebruikt een let, const of class vóór de regel waarop hij wordt gemaakt. Zet de declaratie eerder of verplaats het gebruik naar later.