mitmario.dev

Synthese: der Modul-Baukasten

Node.js Sandbox 3 Min Lesezeit 2 BeispieleLektion 6 von 7

Du kannst jetzt Dateien verbinden. Bleibt die Frage, die dir kein Sprachmittel abnimmt: Welche Dateien soll es überhaupt geben?

Darauf gibt es keine Regel, aber eine Faustregel, die erstaunlich weit trägt.

Eine Datei ist die Antwort auf eine Frage

Nicht auf ein Thema, nicht auf einen Ordner, sondern auf eine Frage, die du in einem Satz stellen kannst. „Wie rechne ich Preise?” ist so eine. „Wie formatiere ich Beträge und Tabellenzeilen?” auch.

Eine Datei, eine Frage
import { euro, tabelle } from "./format.mjs";

console.log(tabelle("Kaffee", euro(23.8)));
console.log(tabelle("Versand", euro(4.9)));

format.mjs beantwortet genau eine Frage, und deshalb weißt du beim nächsten Formatierungsproblem sofort, wo du hinschauen musst. Es steht keine Rechenlogik darin und kein Dateizugriff. Wenn du in einem halben Jahr die Währung wechseln willst, ist klar, wo du anfängst.

Der Gegentest ist genauso einfach: Wenn du den Zweck einer Datei nur mit „und” beschreiben kannst, sind es zwei Dateien.

Warum utils.js ein Warnsignal ist

Fast jedes Projekt hat irgendwann eine Datei namens utils.js, helpers.js oder common.js. Sie fängt mit zwei Funktionen an und hat nach einem Jahr vierzig.

Das liegt daran, dass sie keine Frage beantwortet. Sie sagt nur: hier liegt, was nirgends anders hinpasste. Und weil man das von jeder neuen Funktion auch behaupten kann, wächst sie immer weiter. Am Ende importiert die halbe Anwendung dieselbe Datei, ohne dass jemand sagen könnte, wofür.

Der Ausweg ist nicht, utils.js zu verbieten. Der Ausweg ist, beim Hineinschreiben kurz zu fragen: Wozu gehört das eigentlich? Meistens fällt dir dann der richtige Name ein, und die Datei entsteht von selbst.

Wie ein Programm aus Bausteinen aussieht

Für die Aufgabe gleich liegen drei fertige Module bereit, und die Aufteilung folgt genau dieser Regel:

daten.mjs liefert, was es gibt. preise.mjs macht daraus Zahlen. texte.mjs macht daraus Ausgaben.

Und index.mjs verdrahtet die drei. Diese Datei ist die einzige, die alle drei kennt. Die drei untereinander kennen sich nicht, und genau das macht sie austauschbar: Du kannst die Daten aus einer Datei statt aus einer Liste holen, ohne dass texte.mjs etwas davon merkt.

Diese Aufteilung siehst du in echten Projekten überall wieder. In Abschnitt 18 bekommt sie einen Namen und eine Ordnerstruktur dazu, aber die Idee ist schon hier vollständig.

Wenn zwei Dateien sich gegenseitig brauchen

Es gibt einen Fall, bei dem der Schnitt schiefgegangen ist: a.mjs importiert b.mjs, und b.mjs importiert a.mjs.

Wenn zwei sich gegenseitig brauchen
import "./a.mjs";

Node bricht dabei nicht in eine Endlosschleife aus, sondern arbeitet die Kette ab und lässt den noch nicht fertigen Teil leer. In ESM merkst du das an einem ReferenceError, weil eine Konstante noch nicht bereitsteht. In CommonJS bekämst du an derselben Stelle ein halb gefülltes Objekt und keinen Fehler, was unangenehmer ist.

Die Meldung Cannot access 'a' before initialization ist deshalb ein ziemlich zuverlässiges Zeichen für einen Ringschluss. Wichtiger als die Meldung ist aber, was sie dir sagt: Wenn zwei Dateien einander brauchen, gehört das Gemeinsame meistens in eine dritte. Diese dritte ist dann übrigens genau die Datei, deren Frage vorher niemand gestellt hat.

Zum Mitnehmen

Eine Datei namens utils.js heißt fast immer: Hier liegt alles, wofür noch niemand einen Namen gefunden hat.

Jetzt du

Basis Konto, kostenlos

Zu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.

Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.

In diesem Kurs läuft dein Code auf einem Server. Dafür hat das Basis Konto 1 Stunde im Monat, mehr Zeit gibt es mit dem Premium Konto.

Was in dieser Lektion steckt

  • Artikel mit 2 Beispielen zum Ausprobieren

    Steht hier, ohne Konto lesbar.

  • Aufgabe, dein Code läuft auf einem Server

    Öffnet sich mit dem Basis Konto.