Node.js 13.2.0 bietet ECMAScript- Unterstützung für Module, die für ihre Import- und Exportsyntax bekannt sind. Bisher stand diese Funktionalität hinter dem --experimental-modules
, das nicht mehr benötigt wird. Die Implementierung ist jedoch noch experimentell und kann sich ändern.
Von einem Übersetzer: Mit dieser lang erwarteten Funktion können wir endlich die standardmäßige modulare Syntax verwenden, die bereits in modernen Browsern und jetzt auch in Node.js ohne Flags und Transpiler verfügbar ist
Aktivierung
Node.js verarbeitet den Code in den folgenden Fällen als ES-Module:
- Dateien mit der Erweiterung
.mjs
- Dateien mit der Erweiterung
.js
oder ohne die Erweiterung überhaupt, vorausgesetzt, die nächstgelegene übergeordnete package.json
enthält den Wert "type": "module"
- Code, der zusammen mit dem Flag
—-input-type=module
über das Argument —-eval
oder STDIN übergeben wurde
In allen anderen Fällen wird der Code als CommonJS betrachtet. Dies gilt für .js
Dateien ohne "type": "module"
in der nächsten package.json
und für den Code, der über die Befehlszeile ohne Angabe von --input-type
. Dies geschieht, um die Abwärtskompatibilität zu gewährleisten. Da wir jetzt zwei Arten von Modulen haben, CommonJS und ES, ist es besser, den Modultyp explizit anzugeben.
Sie können Ihren Code mit den folgenden Funktionen explizit als CommonJS kennzeichnen:
- Dateien mit der Erweiterung
.cjs
- Dateien mit der Erweiterung
.js
oder überhaupt ohne Erweiterung, vorausgesetzt, das nächste übergeordnete package.json
enthält den Wert "type": "“commonjs”"
- Code, der über das Argument
--eval
oder STDIN mit dem expliziten Flag --input-type=commonjs
Weitere --input-type
diesen Funktionen finden Sie in den Dokumentationsabschnitten " --input-type
und --input-type
" und unter --input-type
Import und Export von Syntax
Im Kontext des ES-Moduls können Sie den import
und auf andere Javascript-Dateien verweisen. Sie können in einem der folgenden Formate angegeben werden:
- Relative URL:
"./file.mjs"
- Absolute URL c-
file://
, z. B. "file:///opt/app/file.mjs"
"es-module-package"
: "es-module-package"
- Der Pfad zu der Datei im Paket:
"es-module-package/lib/file.mjs"
Bei Importen können Sie Standardwerte ( import _ from "es-module-package"
import { shuffle } from "es-module-package"
) und benannte Werte ( import { shuffle } from "es-module-package"
importieren) sowie alles als einen Namespace import * as fs from "fs"
( import * as fs from "fs"
). Alle integrierten Node.js-Pakete, wie z. B. fs
oder path
, unterstützen alle drei Arten von Importen.
Importe, die auf CommonJS-Code verweisen ( module.exports
alle aktuellen JavaScript- module.exports
die für Node.js require
und module.exports
), können nur die Standardoption verwenden ( import _ from "commonjs-package"
).
Das Importieren anderer Dateiformate wie JSON und WASM bleibt experimentell und erfordert die Flags --experimental-json-modules
und --experimental-wasm-modules
. Sie können diese Dateien jedoch mithilfe der module.createRequire
API herunterladen, die ohne zusätzliche Flags verfügbar ist.
In Ihren ES-Modulen können Sie das Schlüsselwort export verwenden, um Standardwerte und benannte Werte zu exportieren.
Dynamische Ausdrücke mit import()
können zum Laden von ES-Modulen aus CommonJS- oder ES-Code verwendet werden. Beachten Sie, dass import()
kein Modul zurückgibt, sondern dessen Versprechen (Promise).
import.meta.url
ist import.meta.url
in den Modulen verfügbar, die die absolute URL des aktuellen ES-Moduls enthalten.
Dateien und das neue Feld "Typ" in package.json
Fügen Sie "type": "module"
zur package.json Ihres Projekts hinzu, und Node.js beginnt, alle .js
Dateien Ihres Projekts als ES-Module zu erkennen.
Wenn einige Dateien Ihres Projekts weiterhin CommonJS verwenden und Sie nicht das gesamte Projekt auf einmal migrieren können, können Sie entweder die Erweiterung .cjs
für diesen Code verwenden oder sie in ein separates Verzeichnis stellen und package.json
mit dem { "type": "commonjs" }
hinzufügen { "type": "commonjs" }
, was Node.js mitteilt, dass es als CommonJS behandelt werden soll.
Für jede heruntergeladene Datei package.json
Node.js package.json
in dem Verzeichnis, in dem es sich befindet, und dann eine Ebene package.json
usw., bis es das Stammverzeichnis erreicht. Dieser Mechanismus ähnelt der Arbeitsweise von Babel .babelrc
Dateien . Dieser Ansatz ermöglicht es Node.js, package.json
als Quelle für verschiedene Metadaten zum Paket und zur Konfiguration zu verwenden, ähnlich wie es bereits in Babel und anderen Tools funktioniert.
Wir empfehlen allen commonjs
, ein commonjs
anzugeben, auch wenn dort commonjs
geschrieben commonjs
.
Die Paketeintrittspunkte und das Feld "Exporte" in package.json
Jetzt haben wir zwei Felder, um den Einstiegspunkt in das Paket festzulegen: main
und exports
. Das Hauptfeld wird von allen Versionen von Node.js unterstützt, seine Funktionen sind jedoch begrenzt: Damit können Sie nur einen Haupteinstiegspunkt im Paket definieren. Im neuen exports
können Sie auch den Haupteinstiegspunkt sowie zusätzliche Pfade definieren. Dies bietet eine zusätzliche Kapselung für Pakete, bei denen nur die expliziten exports
für den Import von außerhalb des Pakets verfügbar sind. exports
gelten für beide Modultypen, CommonJS und ES, unabhängig davon, ob sie über require
oder import
.
Mit dieser Funktionalität können Importe vom Typ pkg/feature
./node_modules/pkg/esm/feature.js
auf einen realen Pfad wie ./node_modules/pkg/esm/feature.js
. Außerdem gibt Node.js einen Fehler aus, wenn der Import auf pkg/esm/feature.js
verweist, das in den exports
nicht angegeben ist.
Ein zusätzlicher, noch experimenteller, funktionsbedingter Export bietet die Möglichkeit, verschiedene Dateien für verschiedene Umgebungen zu exportieren. Auf diese Weise kann das Paket CommonJS-Code für den Aufruf von require("pkg")
und den ES-Modulcode für den Import durch import "pkg"
, obwohl das Schreiben eines solchen Pakets nicht ohne weitere Probleme ist . Sie können bedingte Exporte mit dem —-experimental-conditional-exports
.
Das Hauptkriterium der neuen Module
Erforderliche Dateierweiterungen
Bei der Verwendung von Importen müssen Sie die Dateierweiterung angeben. Wenn Sie eine Indexdatei aus einem Verzeichnis importieren, müssen Sie auch den Pfad zur Datei vollständig angeben, dh "./startup/index.js".
Dieses Verhalten stimmt mit der Funktionsweise von Importen in Browsern überein, wenn auf einen regulären Server ohne zusätzliche Konfiguration zugegriffen wird.
module.exports
, exports
, module.exports
, __filename
, __dirname
Diese Werte von CommonJS sind im Kontext von ES-Modulen nicht verfügbar. module.createRequire()
kann jedoch über module.createRequire()
in das ES-Modul importiert werden. Die Entsprechungen __filename
und __dirname
erhalten Sie unter import.meta.url
.
Pakete erstellen
Momentan empfehlen wir Paketautoren, für ihre Node.js-Projekte entweder vollständig CommonJS- oder vollständig ES-Module zu verwenden. Die Modularbeitsgruppe für Node.js sucht weiterhin nach Möglichkeiten, die Unterstützung für doppelte Pakete zu verbessern, mit CommonJS für ältere Benutzer und ES-Modulen für neue. Bedingte Exporte sind jetzt experimentell und wir hoffen, diese Funktionalität oder ihre Alternative bis Ende Januar 2020 oder noch früher einführen zu können.
Weitere Informationen hierzu finden Sie in unseren Beispielen und Empfehlungen zum Erstellen von dualen CommonJS / ES-Modulpaketen.
Was wird als nächstes passieren?
Lader. Die Arbeit an der API zum Schreiben benutzerdefinierter Loader, zum Implementieren der Modultranspiration zur Laufzeit, zum Neudefinieren von Importpfaden (Pakete oder einzelne Dateien) und zum Instrumentieren des Codes wird fortgesetzt. Die experimentelle API, die unter dem —-experimental-loader
verfügbar ist, unterliegt erheblichen Änderungen, bevor wir sie vom Flag entfernen.
Dual CommonJS / ES-Modulpakete. Wir möchten eine Standardmethode zum Veröffentlichen eines Pakets bereitstellen, die sowohl über require
in CommonJS als auch über import
in ES-Module verwendet werden kann. Weitere Informationen hierzu finden Sie in der Dokumentation . Wir planen, die Arbeiten abzuschließen und uns bis Ende Januar 2020 von der Fahne zurückzuziehen, wenn nicht früher.
Das ist alles! Wir hoffen, dass die ECMAScript-Unterstützung für Module Node.js den JavaScript-Standards näher bringt und neue Funktionen für die Kompatibilität im gesamten JavaScript-Ökosystem bietet. Der Workflow zur Verbesserung der Modulunterstützung wird hier öffentlich durchgeführt: https://github.com/nodejs/modules .