Layer 8Ehrlicher Tech-Support
SoftwareSchweregrad: LästigERR_PACKAGE_PATH_NOT_EXPORTED

ERR_PACKAGE_PATH_NOT_EXPORTED: Unterpfad nicht importierbar

Import von pkg/lib/util.js scheitert mit ERR_PACKAGE_PATH_NOT_EXPORTED? Das exports-Feld kapselt alle Unterpfade eines Pakets. Ursache und Lösung.

Aufwand:
ca. 20 Min.
Gilt für:
Node.js 20, Node.js 22, Node.js 24

Das Symptom

Du willst nur eine kleine Hilfsfunktion aus einem Paket holen, importierst sie so, wie sie im node_modules-Ordner liegt – und Node bricht ab mit ERR_PACKAGE_PATH_NOT_EXPORTED. Der Text nennt den Paketnamen und den Unterpfad und behauptet, dieser Pfad sei nicht exportiert. Die Datei ist aber da. Du siehst sie. Du kannst sie mit cat ausgeben.

Besonders verwirrend: Dasselbe import lief im letzten Projekt noch. Nur eben mit einer älteren Version desselben Pakets.

Die „Layer 8“-Wahrheit

Die Datei existiert, ja. Sie ist nur nicht für dich gedacht. Node liest im package.json des Pakets das Feld exports, und dieses Feld ist kein Vorschlag, sondern eine Tür mit Schloss: Es „provides a modern alternative to main allowing multiple entry points to be defined“ – und, entscheidend, es verhindert „any other entry points besides those defined in exports“. Die Doku wird an anderer Stelle noch deutlicher: Sobald exports gesetzt ist, sind alle Unterpfade des Pakets gekapselt und für Importeure schlicht nicht mehr vorhanden.

Was hier passiert, ist also kein Fehler, sondern das Gegenteil davon. Jahrelang war jede Datei in node_modules de facto öffentliche Schnittstelle, weil das Dateisystem keine Meinung dazu hatte. Jeder tiefe Import in ein fremdes Paket war eine stille Wette darauf, dass der Autor diese interne Datei nie umbenennt. exports beendet diese Wette – und zwar zugunsten des Autors, der jetzt zum ersten Mal sagen darf, was Zusage ist und was Innenleben.

Der Reflex, jetzt nach einem Schalter zum Abschalten zu suchen, geht am Punkt vorbei. Der Unterpfad ist nicht versehentlich zu, sondern absichtlich. Wenn du ihn brauchst, brauchst du entweder einen anderen, deklarierten Einstiegspunkt – oder ein Gespräch mit dem Paketautor. Nicht einen Umweg, der beim nächsten npm update genauso still zerbricht, wie er entstanden ist.

Die echte, verifizierte Lösung

1000 % faktenbasiert. Jeder Befehl ist real, jeder Pfad existiert. Schritt für Schritt:

  1. 1.

    Prüfen, ob das Paket überhaupt ein exports-Feld hat

    Der Fehler tritt nur auf, wenn das Paket exports deklariert. Die Datei im installierten Paket direkt ansehen, nicht die Doku im Netz – installiert ist, was zählt:

    cat node_modules/<paket>/package.json
    
  2. 2.

    Die deklarierten Unterpfade auslesen

    Im exports-Objekt steht links der Pfad, den Aufrufer benutzen dürfen, rechts die Datei dahinter. Der Haupteinstieg ist der Unterpfad „.“ – alles andere ist zusätzlich erlaubtes Gebiet. Nur diese Schlüssel sind importierbar:

    node -e "console.log(require('<paket>/package.json').exports)"
    
  3. 3.

    Den Import auf einen deklarierten Unterpfad umschreiben

    Statt am Dateisystem entlang zu importieren, den Namen aus exports verwenden. Häufig liegt die gesuchte Funktion ohnehin im Haupteinstieg und der tiefe Import war nie nötig:

    import { helfer } from '<paket>';
    
  4. 4.

    Wenn es das eigene Paket ist: den Unterpfad ergänzen

    Fehlt ein Einstiegspunkt wirklich, gehört er ins exports-Feld. Damit wird er zur bewussten Zusage an alle Aufrufer statt zu einem Zufallsfund im Dateisystem:

    {
      "exports": {
        ".": "./index.js",
        "./submodule.js": "./src/submodule.js"
      }
    }
    
  5. 5.

    Beim fremden Paket den Bedarf melden statt zu tricksen

    Fehlt ein Einstiegspunkt in einem fremden Paket, ist das ein Fall für den Paketautor. Bis dahin ist die stabile Zwischenlösung, die benötigte Logik im eigenen Projekt nachzubauen – nicht, die Kapselung zu unterlaufen.

Häufige Fragen (FAQ)

?Warum funktioniert der tiefe Import in einem anderen Projekt noch?

Weil dort eine ältere Version des Pakets liegt, die noch kein exports-Feld hat. Ohne exports zählt jede Datei im Paketverzeichnis als gültiger Einstiegspunkt. Sobald der Paketautor exports einführt, sind laut Node-Doku alle Unterpfade gekapselt und nur noch das Deklarierte ist erreichbar.

?Kann ich die Kapselung einfach umgehen?

Technisch ja, sinnvoll nein. Der Paketautor hat mit exports bewusst festgelegt, was öffentliche Schnittstelle ist und was Interna sind. Was du an der Kapselung vorbei importierst, kann in der nächsten Patch-Version verschwinden, ohne dass das ein Bruch der Zusage wäre.

Belege

Diese Seite ist gegen die folgenden Primärquellen geprüft – Hersteller, Standard oder Gesetzestext. Wer es nicht glaubt, muss es nicht: Da steht, wo es nachzulesen ist.

Zuletzt geprüft am . Dokumentation altert – ein Datum daneben ist der einzige ehrliche Umgang damit.

Auch zu finden unter

Verwandte Fehler