‫Jonas: Lassen Sie uns als letzten Teil dieses
‫Abschnitts darüber sprechen, wie NODE. JS-Module arbeiten tatsächlich hinter
‫den Kulissen.
‫Zunächst im NODE. JS-Modulsystem wird
‫jede JavaScript-Datei als separates Modul behandelt.
‫Und wir haben schon ein bisschen mit Modulen
‫in der Schnittmenge herumgespielt,
‫'speziell durch die Verwendung der Require-Funktion
‫und den Export von Daten aus Modulen.
‫Das sind also die Grundlagen von Common JS-Modulen,
‫dem Modulsystem, das der Knoten verwendet.
‫Weil es auf dem Server besonders gut funktioniert.
‫Jetzt gibt es auch das native ECMA-Skript oder
‫das ES-Modulsystem, mit
‫dem Sie möglicherweise bereits vertraut sind,
‫insbesondere wenn Sie meinen JavaScript-Kurs besucht
‫haben oder in letzter Zeit
‫JavaScript am Frontend geschrieben haben.
‫Dieses ES-Modulsystem, über das ich gesprochen habe,
‫wurde entwickelt, um im Browser mit der Import-Export-Syntax zu arbeiten.
‫Ich wollte nur klarstellen, dass dies zwei
‫verschiedene Modulsysteme sind, die Sie in verschiedenen
‫Situationen sehen
‫werden, also seien Sie nicht verwirrt.
‫Es gab auch Versuche, native ES-Module in
‫NODE zu implementieren. JS, 'besonders
‫mit Dateierweiterungen wie
‫. mjs.
‫Aber bisher ist
‫es nicht wirklich beliebt geworden.
‫Wenn Sie sich diesen Kurs
‫nicht in ferner
‫Zukunft ansehen, werden Sie wahrscheinlich
‫immer das Common JS-System mit Knoten verwenden.
‫Jetzt fragen Sie sich vielleicht, warum in NODE. JS
‫bekommt jedes einzelne Modul tatsächlich
‫Zugriff auf die require-Funktion,
‫um überhaupt Module zu importieren.
‫Richtig?
‫Ich meine, es ist keine Standard-JavaScript-Funktion.
‫Also woher kommt es?
‫Und wie genau funktioniert es hinter den Kulissen?
‫Nun, lass es uns herausfinden.
‫Die Frage hier
‫ist also, was jedes Mal passiert,
‫wenn wir ein Modul benötigen, indem wir
‫die require-Funktion mit einem Modulnamen aufrufen, ist das Argument.
‫Als sehr breiter Überblick
‫werden die folgenden Schritte hinter den Kulissen ausgeführt.
‫Zunächst wird der Pfad zum
‫gewünschten Modul aufgelöst und die Datei geladen.
‫Danach erfolgt ein Prozess namens
‫Wrapping,
‫der Modulcode wird ausgeführt
‫und die Modulexporte werden zurückgegeben.
‫Und schließlich wird das gesamte Modul zwischengespeichert.
‫Schauen wir uns nun jeden Schritt genauer an.
‫Zunächst einmal, woher weiß Node, welche Datei geladen werden
‫soll, wenn wir ein Modul benötigen?
‫Denken Sie daran, dass wir tatsächlich
‫drei verschiedene Arten von Modulen laden können.
‫Die Kernmodule von Node,
‫unsere eigenen Module oder Module von Drittanbietern von npm wie
‫Express, das ist das Node-Framework, das wir während
‫des größten Teils des Kurses verwenden werden.
‫Dieser Vorgang wird daher als Auflösen des Dateipfads bezeichnet.
‫Und so funktioniert es.
‫Wenn die require-Funktion den Modulnamen als Eingabe
‫erhält, versucht
‫sie zunächst, ein Kernmodul mit diesem Namen zu laden.
‫Wie zum Beispiel das http-Modul.
‫Es findet automatisch einen Pfad zu diesem Modul
‫und lädt es dann.
‫Wenn der Pfad nun mit einem oder zwei
‫Punkten beginnt, bedeutet
‫dies, dass es sich um ein Entwicklermodul handelt.
‫Weil wir den relativen Pfad zu unserer Datei angeben.
‫Der Knoten versucht also, diese Datei zu
‫laden, aber wenn keine Datei mit diesem Namen vorhanden
‫ist, sucht er stattdessen nach einem
‫Ordner und lädt den Index. js, wenn es sich in diesem Ordner befindet.
‫In diesem Beispiel
‫wird also versucht, lib/controller zu laden. js.
‫Denken Sie daran, dass wir den Punkt js
‫weglassen können, wenn Sie ein Modul benötigen.
‫Falls sich in diesem Pfad keine Datei
‫befindet, wird stattdessen
‫versucht, den Index zu öffnen. js aus dem Ordner lib/controller.
‫Sinn ergeben?
‫Und schließlich, wenn das erforderliche Modul
‫weder ein Kernmodul noch
‫ein Entwicklermodul ist, geht node davon
‫aus, dass es sich um ein Modul von npm handelt.
‫Und denken Sie daran, dass wir bei einem Modul, das wir von npm
‫laden, den Pfad tatsächlich nicht schreiben müssen, wenn wir ihn benötigen.
‫Nur der
‫Modulname, so wie es bei einem Kernmodul funktioniert.
‫Diese Module von Drittanbietern werden also in
‫einem Knotenmodulordner gespeichert, sodass der
‫Knoten in diesen Ordner wechselt und versucht, dort ein
‫Modul zu finden und es dann zu laden.
‫Und wenn die Datei nirgendwo gefunden werden kann,
‫wird natürlich ein Fehler ausgegeben und die
‫Ausführung der App gestoppt.
‫Nachdem das Modul geladen wurde,
‫wird der Code des Moduls in eine spezielle Funktion
‫verpackt, die uns Zugriff auf einige spezielle Objekte gibt.
‫In diesem Schritt passiert also die Magie.
‫Hier bekommen wir die Antwort auf die
‫Frage, woher kommt eigentlich die require-Funktion und warum
‫haben wir Zugriff darauf?
‫Dies liegt daran, dass die
‫Laufzeit von nodejs den
‫Code aus unserem Modul entfernt und ihn in
‫den sofort aufgerufenen Funktionsausdruck oder IIFE einfügt, den Sie hier sehen können.
‫Node führt also nicht
‫direkt den Code aus, den ich in eine
‫Datei umschreibe, sondern stattdessen die Wrapper-Funktion, die unseren
‫Code in seinem Körper enthält.
‫Es gibt auch die von
‫Experten benötigten Module, Dateinamen und dir-Objekte hinein.
‫Deshalb haben wir in jedem
‫Modul automatisch Zugriff
‫auf Dinge wie die require-Funktion.
‫Diese sind also im Grunde wie
‫globale Variablen, die in jedes einzelne Modul eingefügt werden.
‫Dadurch erreicht node nun zwei sehr wichtige Dinge.
‫Erstens besteht natürlich darin, Entwicklern Zugriff auf all diese
‫Variablen zu geben, über die wir gerade gesprochen
‫haben, was sehr hilfreich ist.
‫Zweitens bleiben die Variablen der obersten Ebene, die
‫wir in unseren Modulen definieren, privat.
‫Es ist also nur auf das aktuelle
‫Modul beschränkt, anstatt alles in das globale Objekt zu übertragen.
‫Stellen Sie sich
‫für eine Sekunde vor, dass wir in einem unserer Module eine
‫Variable x deklariert haben und dann ein npm-Modul eingebunden haben, das
‫ebenfalls eine Variable namens x verwendet.
‫Ohne diesen Mechanismus würde
‫dann unsere eigene Variable überschrieben und
‫die gesamte App würde einfach nicht funktionieren.
‫Daher ist jedes Modul mit seinem privaten
‫Geltungsbereich absolut entscheidend und wird durch diesen
‫cleveren Trick erreicht, unseren Code in diese spezielle
‫Funktion zu packen.
‫Werfen wir nun einen kurzen Blick auf jedes
‫Objekt, das unser Modul erhält.
‫Zuerst die require-Funktion, die
‫wir bereits kennen.
‫Dann gibt es noch ein Modul-Objekt,
‫das nur eine Referenz auf das aktuelle Modul
‫ist und für uns am
‫wichtigsten ist, wenn es um den Datenexport geht.
‫Das gleiche gilt für das Objekt des
‫Exports, das wir gleich besprechen werden.
‫Schließlich gibt es noch
‫die Komfortvariablen file name und dir
‫name, die einfach den absoluten
‫Pfad zur Datei
‫des aktuellen Moduls sowie den aktuellen Verzeichnisnamen enthalten.
‫Und so funktioniert der Wrapping-Schritt beim Laden eines Moduls.
‫Als nächstes wird der Code im
‫Modul, genauer gesagt
‫in der Wrapper-Funktion des Moduls,
‫tatsächlich vom NODE ausgeführt. JS-Laufzeit.
‫Also nichts Besonderes hier.
‫Bis zu
‫diesem Punkt wurde die require-Funktion mit einem
‫Modulnamen als Argument aufgerufen,
‫der Pfad zur Moduldatei wurde in Datei geladen aufgelöst,
‫der gesamte Code wurde in die Wrapper-Funktion
‫verpackt, die dann ausgeführt wurde.
‫Jetzt ist es an der Zeit, dass
‫die require-Funktion tatsächlich etwas zurückgibt.
‫Und was es zurückgibt, sind die Exporte des erforderlichen Moduls.
‫Diese Exporte werden im Modul gespeichert. exportiertObjekte.
‫Es könnte ein bisschen so aussehen.
‫Auch hier können wir in jedem Modul
‫Variablen exportieren, die am Ende von der require-Funktion zurückgegeben werden.
‫Und das tun wir, indem wir dem Modul Variablen zuweisen. exports oder einfach zu exports, wo
‫es nur ein
‫Zeiger auf das Modul ist. Export.
‫Wir werden dies im nächsten Video
‫praktisch tun, weil ich weiß, dass das etwas verwirrend
‫klingt, wenn ich es nur so sage.
‫Wie auch immer, hier ist, was Sie
‫wissen müssen, wann Sie das Modul verwenden sollten. exportieren oder nur exportieren.
‫Wenn Sie also nur eine einzelne Variable exportieren möchten, beispielsweise
‫eine Klasse oder eine Funktion, verwenden
‫Sie normalerweise module. exports und setzen Sie es
‫gleich der Variablen, die Sie exportieren möchten.
‫Genau wie in diesem Beispiel.
‫Wenn
‫Sie andererseits mehrere benannte Variablen wie beispielsweise
‫mehrere Funktionen exportieren möchten,
‫sollten Sie
‫diese als Eigenschaften des Exportobjekts erstellen.
‫Wenn wir beispielsweise ein Rechnermodul erstellen würden, könnten Sie
‫Exporte erstellen. hinzufügen, exportiert.
‫multiplizieren, exportieren. teilen und so weiter und so weiter.
‫Macht Sinn?
‫Auch dies werden wir im nächsten Video tun und es
‫wird bis dahin für Sie mehr Sinn ergeben.
‫Auf diese Weise exportieren und importieren wir Daten von
‫einem Modul in das andere.
‫Das ist natürlich auch der Grund,
‫warum wir normalerweise das Ergebnis einer aufgerufenen require-Funktion einer neuen Variablen zuweisen.
‫Damit wir die zurückgegebenen Exporte speichern können.
‫Um dieses Video ganz schnell
‫zu beenden, ist der letzte Schritt, dass Module
‫nach dem ersten Laden tatsächlich zwischengespeichert werden.
‫Das heißt, wenn Sie das gleiche Modul
‫mehrmals benötigen, erhalten Sie immer das gleiche Ergebnis.
‫Und der Code in den Modulen wird eigentlich nur beim
‫ersten Aufruf ausgeführt.
‫Bei nachfolgenden Aufrufen
‫wird das Ergebnis einfach aus dem Cache abgerufen.
‫Perfekt.
‫Ich hoffe also, dass die ganze
‫Logik hinter der Arbeit
‫mit Modulen nicht mehr wirklich wie Zauberei aussieht.
‫Es ist wirklich wichtig zu wissen, wie das alles
‫funktioniert, um ein großartiger und
‫vor allem unabhängigerer NODE
‫zu werden. JS-Entwickler.