Node.js-Schnelleinführungskurs: Geben Sie ein, um zu lernen
Vor zwei Jahren habe ich einen Artikel geschrieben, der das Modulsystem vorstellt: Verständnis des Konzepts von Front-End-Modulen: CommonJs und ES6Module. Das Wissen in diesem Artikel richtet sich an Anfänger und ist relativ einfach. Hier korrigieren wir auch ein paar Fehler im Artikel:
[Modul] und [Modulsystem] sind zwei verschiedene Dinge. Ein Modul ist eine Einheit in der Software, und ein Modulsystem ist ein Satz von Syntax oder Werkzeugen. Das Modulsystem ermöglicht Entwicklern, Module in Projekten zu definieren und zu verwenden.
Die Abkürzung für ECMAScript Module lautet ESM oder ESModule, nicht ES6Module.
Das Grundwissen über das Modulsystem wurde im vorherigen Artikel fast abgedeckt, daher konzentriert sich dieser Artikel auf die internen Prinzipien des Modulsystems und eine umfassendere Einführung in die Unterschiede zwischen verschiedenen Modulsystemen. Der Inhalt des vorherigen Artikels ist hier wird nicht noch einmal wiederholt.
Nicht alle Programmiersprachen verfügen über ein integriertes Modulsystem, und JavaScript hatte nach seiner Geburt lange Zeit kein Modulsystem.
In der Browserumgebung können Sie das <script>
-Tag nur zum Einführen nicht verwendeter Codedateien verwenden. Diese Methode weist einen gemeinsamen globalen Geltungsbereich auf. In Verbindung mit der schnellen Entwicklung des Frontends ist diese Methode nicht vorhanden entspricht nicht mehr den aktuellen Bedürfnissen. Bevor das offizielle Modulsystem erschien, erstellte die Front-End-Community ein eigenes Modulsystem von Drittanbietern. Die am häufigsten verwendeten sind: asynchrone Moduldefinition AMD , universelle Moduldefinition UMD usw. Das bekannteste ist natürlich CommonJS .
Da Node.js eine JavaScript-Laufzeitumgebung ist, kann es direkt auf das zugrunde liegende Dateisystem zugreifen. Deshalb haben die Entwickler es übernommen und ein Modulsystem gemäß den CommonJS-Spezifikationen implementiert.
Zunächst konnte CommonJS nur auf der Node.js-Plattform verwendet werden. Mit dem Aufkommen von Modulpaketierungstools wie Browserify und Webpack kann CommonJS endlich auf der Browserseite ausgeführt werden.
Erst mit der Veröffentlichung der ECMAScript6-Spezifikation im Jahr 2015 gab es einen formalen Standard für das Modulsystem. Das nach diesem Standard erstellte Modulsystem wurde kurz ECMAScript-Modul (ESM) genannt die Node.js-Umgebung und die Browserumgebung. Natürlich stellt ECMAScript6 nur Syntax und Semantik bereit. Für die Implementierung müssen verschiedene Browserdienstanbieter und Node-Entwickler hart arbeiten. Aus diesem Grund haben wir das Babel- Artefakt, um das uns andere Programmiersprachen beneiden. Die Implementierung eines Modulsystems ist keine einfache Aufgabe. Node.js unterstützt ESM nur in Version 13.2.
Aber egal was passiert, ESM ist der „Sohn“ von JavaScript und es ist nichts Falsches daran, es zu lernen!
Im Zeitalter des Slash-and-Burn-Farmings wurde JavaScript zur Entwicklung von Anwendungen verwendet, und Skriptdateien konnten nur über Skript-Tags eingeführt werden. Eines der schwerwiegenderen Probleme ist das Fehlen eines Namespace-Mechanismus, was bedeutet, dass jedes Skript denselben Gültigkeitsbereich hat. Für dieses Problem gibt es in der Community eine bessere Lösung: das Revevaling-Modul
const myModule = (() => { const _privateFn = () => {} const_privateAttr = 1 zurückkehren { publicFn: () => {}, publicAttr: 2 } })() console.log(myModule) console.log(myModule.publicFn, myModule._privateFn)
Die Laufergebnisse sind wie folgt:
Dieses Muster ist sehr einfach: Verwenden Sie IIFE , um einen privaten Bereich zu erstellen, und verwenden Sie Rückgabevariablen zur Offenlegung. Auf interne Variablen (z. B. _privateFn, _privateAttr) kann von außen nicht zugegriffen werden.
[revealing module] nutzt diese Funktionen, um private Informationen zu verbergen und APIs zu exportieren, die der Außenwelt zugänglich gemacht werden sollten. Auf dieser Idee basiert auch die Entwicklung des nachfolgenden Modulsystems.
Entwickeln Sie basierend auf den oben genannten Ideen einen Modullader.
Schreiben Sie zunächst eine Funktion, die den Modulinhalt lädt, packen Sie diese Funktion in einen privaten Bereich und werten Sie sie dann über eval() aus, um die Funktion auszuführen:
Funktion LoadModule (Dateiname, Modul, erforderlich) { const WrappedSrc = `(Funktion (Modul, Exporte, erfordern) { ${fs.readFileSync(filename, 'utf8)} }(module, module.exports, require)` eval(wrappedSrc) }
Wie beim [offenbaren Modul] wird der Quellcode des Moduls in eine Funktion eingeschlossen. Der Unterschied besteht darin, dass auch eine Reihe von Variablen (module, module.exports, require) an die Funktion übergeben werden.
Es ist zu beachten, dass der Modulinhalt über [readFileSync] gelesen wird. Im Allgemeinen sollten Sie die synchronisierte Version nicht verwenden, wenn Sie APIs aufrufen, die das Dateisystem betreffen. Diesmal ist es jedoch anders, da das Laden von Modulen über das CommonJs-System selbst als synchroner Vorgang implementiert werden sollte, um sicherzustellen, dass mehrere Module in der richtigen Abhängigkeitsreihenfolge eingeführt werden können.
Simulieren Sie dann die Funktion require(), deren Hauptfunktion darin besteht, das Modul zu laden.
Funktion require(moduleName) { const id = require.resolve(moduleName) if (require.cache[id]) { Geben Sie require.cache[id].exports zurück } // Modulmetadaten const module = { Exporte: {}, AUSWEIS } //Cache aktualisieren require.cache[id] = module //Modul laden LoadModule(id, module, require) // Exportierte Variablen zurückgeben return module.exports } require.cache = {} require.resolve = (moduleName) => { // Analysiere die vollständige Modul-ID basierend auf moduleName }
(1) Nachdem die Funktion den Modulnamen empfangen hat, analysiert sie zunächst den vollständigen Pfad des Moduls und weist ihn der ID zu.
(2) Wenn cache[id]
wahr ist, bedeutet dies, dass das Modul geladen wurde und das Cache-Ergebnis direkt zurückgegeben wird. (3) Andernfalls wird eine Umgebung für das erste Laden konfiguriert. Erstellen Sie insbesondere ein Modulobjekt, einschließlich Exporte (dh exportierter Inhalt) und ID (die Funktion ist wie oben).
(4) Zwischenspeichern des zum ersten Mal geladenen Moduls (5) Lesen des Quellcodes aus der Quelldatei des Moduls über LoadModule (6) Abschließend gibt return module.exports
den Inhalt zurück, den Sie exportieren möchten.
Bei der Simulation der Anforderungsfunktion gibt es ein sehr wichtiges Detail: Die Anforderungsfunktion muss synchron sein . Seine Funktion besteht nur darin, den Modulinhalt direkt zurückzugeben, und verwendet keinen Rückrufmechanismus. Das Gleiche gilt für require in Node.js. Daher muss die Zuweisungsoperation für module.exports auch synchron sein. Wenn asynchron verwendet wird, treten Probleme auf:
// Etwas ist schiefgegangen setTimeout(() => { module.exports = function () {} }, 1000)
Die Tatsache, dass es sich bei require um eine synchrone Funktion handelt, hat einen sehr wichtigen Einfluss auf die Art und Weise, Module zu definieren, da sie uns dazu zwingt, beim Definieren von Modulen nur synchronen Code zu verwenden, sodass Node.js für diesen Zweck synchrone Versionen der meisten asynchronen APIs bereitstellt.
Frühe Node.js verfügten über eine asynchrone Version der Funktion „require“, die jedoch schnell entfernt wurde, da sie die Funktion sehr kompliziert machen würde.
ESM ist Teil der ECMAScript2015-Spezifikation, die ein offizielles Modulsystem für die JavaScript-Sprache zur Anpassung an verschiedene Ausführungsumgebungen spezifiziert.
Standardmäßig behandelt Node.js Dateien mit dem Suffix .js so, als wären sie mit der CommonJS-Syntax geschrieben. Wenn Sie die ESM-Syntax direkt in der .js-Datei verwenden, meldet der Interpreter einen Fehler.
Es gibt drei Möglichkeiten, den Node.js-Interpreter in die ESM-Syntax zu konvertieren:
1. Ändern Sie die Dateierweiterung in .mjs;
2. Fügen Sie der neuesten package.json-Datei ein Typfeld mit dem Wert „module“ hinzu;
3. Die Zeichenfolge wird als Parameter an --eval
übergeben oder über die STDIN-Pipe mit dem Flag --input-type=module
an den Knoten übertragen
Zum Beispiel:
node --input-type=module --eval "import { sep } from 'node:path'; console.log(sep);"
ESM kann als URL analysiert und zwischengespeichert werden (was auch bedeutet, dass Sonderzeichen prozentual codiert werden müssen). Unterstützt URL-Protokolle wie file:
node:
und data:
Datei:URL
Das Modul wird mehrmals geladen, wenn der zum Auflösen des Moduls verwendete Importspezifizierer unterschiedliche Abfragen oder Fragmente enthält
// Wird als zwei verschiedene Module betrachtet import './foo.mjs?query=1'; import './foo.mjs?query=2';
Daten:URL
Unterstützt den Import mithilfe von MIME-Typen:
text/javascript
für ES-Module
application/json
für JSON
application/wasm
für Wasm
import 'data:text/javascript,console.log("hello!");'; import _ from 'data:application/json,"world!"' Assert { type: 'json' };
data:URL
analysiert nur reine und absolute Spezifizierer für integrierte Module. Das Parsen relativer Spezifizierer funktioniert nicht, da data:
kein spezielles Protokoll ist und kein Konzept für relatives Parsen hat.
Import Assertion <br/>Dieses Attribut fügt der Modulimportanweisung Inline-Syntax hinzu, um neben dem Modulspezifizierer weitere Informationen zu übergeben.
fooData aus './foo.json' importieren Assert { Typ: 'json' }; const { default: barData } = waiting import('./bar.json', { Assert: { Type: 'json' } });
Derzeit wird nur das JSON-Modul unterstützt und assert { type: 'json' }
-Syntax ist obligatorisch.
Wash-Module importieren <br/>Der Import von WebAssembly-Modulen wird unter der Flagge --experimental-wasm-modules
unterstützt, sodass jede .wasm-Datei als normales Modul importiert werden kann und gleichzeitig der Import ihrer Module unterstützt wird.
// index.mjs import * als M aus './module.wasm'; console.log(M)
Verwenden Sie zum Ausführen den folgenden Befehl:
Knoten --experimental-wasm-modules index.mjs
Das Schlüsselwort „await“ kann auf der obersten Ebene in ESM verwendet werden.
// a.mjs export const five = Warten auf Promise.resolve(5) // b.mjs importiere { five } aus './a.mjs' console.log(fünf) // 5
Wie bereits erwähnt, ist die Auflösung von Modulabhängigkeiten durch die Importanweisung statisch und weist daher zwei bekannte Einschränkungen auf:
Modulbezeichner können nicht bis zur Laufzeit warten, um sie zu erstellen.
Modulimportanweisungen müssen am Anfang der Datei geschrieben werden und können nicht in Kontrollflussanweisungen verschachtelt werden.
Für manche Situationen sind diese beiden Einschränkungen jedoch zweifellos zu streng. Beispielsweise gibt es eine relativ häufige Anforderung: Lazy Loading :
Wenn Sie auf ein großes Modul stoßen, möchten Sie dieses riesige Modul nur dann laden, wenn Sie wirklich eine bestimmte Funktion im Modul verwenden müssen.
Zu diesem Zweck stellt ESM einen asynchronen Einführungsmechanismus bereit. Diese Einführungsoperation kann über import()
Operator erreicht werden, wenn das Programm ausgeführt wird. Aus syntaktischer Sicht entspricht es einer Funktion, die einen Modulbezeichner als Parameter empfängt und ein Versprechen zurückgibt. Nachdem das Versprechen aufgelöst wurde, kann das analysierte Modulobjekt abgerufen werden.
Verwenden Sie ein Beispiel einer zirkulären Abhängigkeit, um den ESM-Ladevorgang zu veranschaulichen:
// index.js import * as foo from './foo.js'; * als Bar aus './bar.js' importieren; console.log(foo); console.log(bar); // foo.js * als Bar aus './bar.js' importieren export letloaded = false; export const bar = Bar; geladen = wahr; //bar.js import * als Foo aus './foo.js'; export letloaded = false; export const foo = Foo; geladen = wahr
Werfen wir zunächst einen Blick auf die Laufergebnisse:
Durch geladen kann beobachtet werden, dass beide Module foo und bar die gesamten geladenen Modulinformationen protokollieren können. Aber CommonJS ist anders. Es muss ein Modul geben, das nach dem vollständigen Laden nicht ausdrucken kann.
Lassen Sie uns in den Ladevorgang eintauchen, um zu sehen, warum dieses Ergebnis auftritt.
Der Ladevorgang kann in drei Phasen unterteilt werden:
Die erste Stufe: Analyse
Zweite Stufe: Erklärung
Die dritte Stufe: Ausführung
Parsing-Phase:
Der Interpreter beginnt mit der Eintragsdatei (d. h. index.js), analysiert die Abhängigkeiten zwischen Modulen und zeigt sie in Form eines Diagramms an. Dieses Diagramm wird auch als Abhängigkeitsdiagramm bezeichnet.
In diesem Stadium konzentrieren wir uns nur auf die Importanweisungen und laden den Quellcode, der den Modulen entspricht, die diese Anweisungen einführen möchten. Und erhalten Sie das endgültige Abhängigkeitsdiagramm durch eine eingehende Analyse. Nehmen Sie das obige Beispiel zur Veranschaulichung:
1. Suchen Sie ausgehend von index.js import * as foo from './foo.js'
und gehen Sie zur Datei foo.js.
2. Fahren Sie mit dem Parsen der Datei foo.js fort und suchen Sie import * as Bar from './bar.js'
und gehen Sie so zu bar.js.
3. Fahren Sie mit dem Parsen von bar.js fort und suchen Sie import * as Foo from './foo.js'
, die eine zirkuläre Abhängigkeit bildet. Da der Interpreter jedoch bereits das foo.js-Modul verarbeitet, wird er es nicht eingeben erneut und fahren Sie dann mit dem Parsen des Balkenmoduls fort.
4. Nach dem Parsen des Bar-Moduls wird festgestellt, dass keine Importanweisung vorhanden ist. Daher kehrt es zu foo.js zurück und setzt das Parsen fort. Die Importanweisung wurde nicht vollständig wiedergefunden und index.js wurde zurückgegeben.
5. import * as bar from './bar.js'
wird in index.js gefunden, aber da bar.js bereits analysiert wurde, wird es übersprungen und die Ausführung fortgesetzt.
Schließlich wird das Abhängigkeitsdiagramm durch den Tiefenansatz vollständig angezeigt:
Deklarationsphase:
Der Interpreter beginnt mit dem erhaltenen Abhängigkeitsdiagramm und deklariert jedes Modul in der Reihenfolge von unten nach oben. Konkret werden bei jedem Erreichen eines Moduls alle vom Modul zu exportierenden Eigenschaften durchsucht und die Bezeichner der exportierten Werte im Speicher deklariert. Bitte beachten Sie, dass in dieser Phase nur Deklarationen vorgenommen und keine Zuweisungsvorgänge durchgeführt werden.
1. Der Interpreter beginnt mit dem bar.js-Modul und deklariert die Bezeichner von „loaded“ und „foo“.
2. Verfolgen Sie zurück zum foo.js-Modul und deklarieren Sie die geladenen und bar-Bezeichner.
3. Wir sind beim Modul index.js angekommen, aber dieses Modul hat keine Exportanweisung, daher ist kein Bezeichner deklariert.
Nachdem Sie alle Export-IDs deklariert haben, gehen Sie das Abhängigkeitsdiagramm erneut durch, um die Beziehung zwischen Import und Export herzustellen.
Es ist ersichtlich, dass eine Bindungsbeziehung ähnlich const zwischen dem durch Import eingeführten Modul und dem durch Export exportierten Wert hergestellt wird. Die importierende Seite kann nur lesen, aber nicht schreiben. Darüber hinaus sind das in index.js gelesene Balkenmodul und das in foo.js gelesene Balkenmodul im Wesentlichen dieselbe Instanz.
Aus diesem Grund werden in den Ergebnissen dieses Beispiels die vollständigen Parsing-Ergebnisse ausgegeben.
Dies unterscheidet sich grundlegend vom Ansatz des CommonJS-Systems. Wenn ein Modul ein CommonJS-Modul importiert, kopiert das System dessen gesamtes Exportobjekt und kopiert seinen Inhalt in das aktuelle Modul. Wenn das importierte Modul in diesem Fall seine eigene Kopiervariable ändert, kann der Benutzer den neuen Wert nicht sehen .
Ausführungsphase:
In diesem Stadium führt die Engine den Code des Moduls aus. Der Zugriff auf das Abhängigkeitsdiagramm erfolgt weiterhin in der Reihenfolge von unten nach oben und die Dateien, auf die zugegriffen wird, werden einzeln ausgeführt. Die Ausführung beginnt in der Datei bar.js, geht über foo.js und schließlich index.js. Dabei wird der Wert der Kennung in der Exporttabelle schrittweise verbessert.
Dieser Prozess scheint sich nicht wesentlich von CommonJS zu unterscheiden, es gibt jedoch tatsächlich große Unterschiede. Da CommonJS dynamisch ist, analysiert es das Abhängigkeitsdiagramm, während es zugehörige Dateien ausführt. Solange Sie also eine require-Anweisung sehen, können Sie sicher sein, dass alle vorherigen Codes ausgeführt wurden, wenn das Programm zu dieser Anweisung kommt. Daher muss die require-Anweisung nicht unbedingt am Anfang der Datei stehen, sondern kann überall stehen, und Modulbezeichner können auch aus Variablen erstellt werden.
Bei ESM ist es jedoch anders. Die oben genannten drei Phasen müssen zunächst vollständig erstellt werden, bevor der Code ausgeführt werden kann. Warten Sie nicht, bis der Code ausgeführt wird.
Zusätzlich zu den verschiedenen zuvor erwähnten Unterschieden gibt es einige bemerkenswerte Unterschiede:
Wenn Sie das Schlüsselwort „import“ in ESM verwenden, um relative oder absolute Spezifizierer aufzulösen, muss die Dateierweiterung angegeben und der Verzeichnisindex („./path/index.js“) vollständig angegeben werden. Die CommonJS-Require-Funktion ermöglicht das Weglassen dieser Erweiterung.
ESM wird standardmäßig im strikten Modus ausgeführt und dieser strikte Modus kann nicht deaktiviert werden. Daher können Sie weder nicht deklarierte Variablen noch Funktionen verwenden, die nur im nicht strikten Modus verfügbar sind (z. B. mit).
CommonJS stellt einige globale Variablen bereit, die unter ESM nicht verwendet werden können. Wenn Sie versuchen, diese Variablen zu verwenden, tritt ein ReferenceError auf. enthalten
require
exports
module.exports
__filename
__dirname
Unter diesen bezieht sich __filename
auf den absoluten Pfad der aktuellen Moduldatei und __dirname
auf den absoluten Pfad des Ordners, in dem sich die Datei befindet. Diese beiden Variablen sind beim Erstellen des relativen Pfads der aktuellen Datei sehr hilfreich. Daher bietet ESM einige Methoden zum Implementieren der Funktionen der beiden Variablen.
In ESM können Sie das Objekt import.meta
verwenden, um eine Referenz zu erhalten, die auf die URL der aktuellen Datei verweist. Insbesondere wird der Dateipfad des aktuellen Moduls über import.meta.url
abgerufen. Das Format dieses Pfads ähnelt file:///path/to/current_module.js
. Basierend auf diesem Pfad wird der durch __filename
und __dirname
ausgedrückte absolute Pfad erstellt:
{ fileURLToPath } aus 'URL' importieren { Verzeichnisname } aus 'Pfad' importieren const __filename = fileURLToPath(import.meta.url) const __dirname = dirname(__filename)
Es kann auch die Funktion require() in CommonJS simulieren
importiere { createRequire } aus 'Modul' const require = createRequire(import.meta.url)
Im globalen ESM-Bereich ist dies undefiniert, im CommonJS-Modulsystem handelt es sich jedoch um einen Verweis auf Exporte:
//ESM console.log(this) // undefiniert // CommonJS console.log(this === exports) // true
Wie oben erwähnt, kann die CommonJS-Funktion require() in ESM simuliert werden, um CommonJS-Module zu laden. Darüber hinaus können Sie auch die Standard-Importsyntax verwenden, um CommonJS-Module einzuführen. Diese Importmethode kann jedoch nur standardmäßig exportierte Dinge importieren:
import packageMain from 'commonjs-package' // Es ist durchaus möglich, { method } aus 'commonjs-package' zu importieren // Fehler
Die Anforderung des CommonJS-Moduls behandelt die Dateien, auf die es verweist, immer als CommonJS. Das Laden von ES-Modulen mit „require“ wird nicht unterstützt, da ES-Module über eine asynchrone Ausführung verfügen. Sie können import()
jedoch verwenden, um ES-Module aus CommonJS-Modulen zu laden.
Obwohl ESM seit 7 Jahren auf dem Markt ist, wird es auch von node.js stabil unterstützt. Bei der Entwicklung von Komponentenbibliotheken können wir nur ESM unterstützen. Um aber auch mit alten Projekten kompatibel zu sein, ist die Unterstützung von CommonJS unerlässlich. Es gibt zwei weit verbreitete Methoden, um eine Komponentenbibliothek zu erstellen, die Exporte aus beiden Modulsystemen unterstützt.
Schreiben Sie Pakete in CommonJS oder konvertieren Sie den ES-Modul-Quellcode in CommonJS und erstellen Sie ES-Modul-Wrapper-Dateien, die benannte Exporte definieren. Verwenden Sie den bedingten Export, beim Import wird der ES-Modul-Wrapper verwendet und bei require wird der CommonJS-Einstiegspunkt verwendet. Beispielsweise im Beispielmodul
// package.json { „Typ“: „Modul“, "Exporte": { „import“: „./wrapper.mjs“, „require“: „./index.cjs“ } }
Verwenden Sie die Anzeigeerweiterungen .cjs
und .mjs
, da bei Verwendung von nur .js
entweder standardmäßig CommonJS verwendet wird oder "type": "module"
dazu führt, dass diese Dateien als ES-Module behandelt werden.
// ./index.cjs export.name = 'name'; // ./wrapper.mjs cjsModule aus „./index.cjs“ importieren export const name = cjsModule.name;
In diesem Beispiel:
// ESM verwenden, um import { name } aus „example“ einzuführen // CommonJS verwenden, um const { name } = require('example') einzuführen
Der auf beide Arten eingeführte Name ist derselbe Singleton.
Die Datei package.json kann direkt separate Einstiegspunkte für CommonJS- und ES-Module definieren:
// package.json { „Typ“: „Modul“, "Exporte": { „import“: „./index.mjs“, „require“: „./index.cjs“ } }
Dies ist möglich, wenn die CommonJS- und ESM-Versionen des Pakets gleichwertig sind, z. B. weil es sich bei einer um eine transpilierte Ausgabe der anderen handelt und die Statusverwaltung des Pakets sorgfältig isoliert ist (oder das Paket zustandslos ist).
Der Grund dafür, dass der Status ein Problem darstellt, liegt darin, dass sowohl die CommonJS- als auch die ESM-Version des Pakets in der Anwendung verwendet werden können. Beispielsweise kann der Referrer-Code des Benutzers die ESM-Version importieren, während die Abhängigkeit die CommonJS-Version erfordert. In diesem Fall werden zwei Kopien des Pakets in den Speicher geladen, sodass zwei unterschiedliche Zustände auftreten. Dies kann zu Fehlern führen, die schwer zu beheben sind.
Zusätzlich zum Schreiben zustandsloser Pakete (wenn beispielsweise JavaScripts Math ein Paket wäre, wäre es zustandslos, da alle seine Methoden statisch sind), gibt es Möglichkeiten, den Zustand zu isolieren, sodass er in potenziell geladenen CommonJS- und ESM-Paketen verwendet werden kann Paketinstanzen:
Wenn möglich, schließen Sie alle Zustände in das instanziierte Objekt ein. Beispielsweise muss das Datum von JavaScript instanziiert werden, um den Status zu enthalten. Wenn es sich um ein Paket handelt, wird es wie folgt verwendet:
Importdatum aus 'Datum'; const someDate = new Date(); // someDate enthält den Status; Date nicht
Das Schlüsselwort new ist nicht erforderlich; Paketfunktionen können neue Objekte zurückgeben oder übergebene Objekte ändern, um den Status außerhalb des Pakets beizubehalten.
Isolieren Sie den Status in einer oder mehreren CommonJS-Dateien, die von den CommonJS- und ESM-Versionen eines Pakets gemeinsam genutzt werden. Die Einstiegspunkte für CommonJS und ESM sind beispielsweise index.cjs bzw. index.mjs:
// index.cjs const state = require('./state.cjs') module.exports.state = Zustand; // index.mjs Status aus './state.cjs' importieren exportieren { Zustand }
Selbst wenn ein Beispiel über „require“ und „import“ in einer Anwendung verwendet wird, enthält jeder Verweis auf ein Beispiel denselben Status, und Änderungen des Status durch eines der Modulsysteme gelten für beide.
Wenn dieser Artikel für Sie hilfreich ist, geben Sie ihm bitte ein „Gefällt mir“ und unterstützen Sie ihn. Ihr „Gefällt mir“ ist für mich die Motivation, weiter zu schreiben.
In diesem Artikel werden die folgenden Informationen zitiert:
Offizielle Dokumentation von node.js
Node.js-Entwurfsmuster