Wir kündigen die Unterstützung für ECMAScript-Module in Node.js an

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 .

Source: https://habr.com/ru/post/de477168/


All Articles