it-swarm.com.de

Für die Verwendung von Node.js ist der Import / Export mit ES6 erforderlich

In einem Projekt, an dem ich zusammenarbeite, haben wir zwei Möglichkeiten, welches Modulsystem wir verwenden können:

  1. Importieren von Modulen mit require und Exportieren mit module.exports und exports.foo.
  2. Module mit ES6 import importieren und mit ES6 export exportieren

Gibt es irgendwelche Leistungsvorteile, wenn man eins über das andere verwendet? Gibt es noch etwas, das wir wissen sollten, wenn wir ES6-Module anstelle von Node verwenden würden?

792
kpimov

Gibt es irgendwelche Leistungsvorteile, wenn man eins über das andere verwendet?

Beachten Sie, dass es noch keine JavaScript-Engine gibt, die ES6-Module nativ unterstützt. Du hast selbst gesagt, dass du Babel benutzt. Babel konvertiert die import- und export -Deklaration ohnehin standardmäßig in CommonJS (require/module.exports). Selbst wenn Sie die ES6-Modulsyntax verwenden, verwenden Sie CommonJS unter der Haube, wenn Sie den Code in Node ausführen.

Es gibt technische Unterschiede zwischen CommonJS- und ES6-Modulen, z. Mit CommonJS können Sie Module dynamisch laden. ES6 lässt dies nicht zu, dafür ist eine API in der Entwicklung .

Da ES6-Module Teil des Standards sind, würde ich sie verwenden.

642
Felix Kling

Es gibt verschiedene Verwendungsmöglichkeiten, die Sie in Betracht ziehen sollten:

Benötigen:

  • Sie können dynamisch laden, wenn der Name des geladenen Moduls nicht vordefiniert/statisch ist oder wenn Sie ein Modul nur bedingt laden, wenn es "wirklich erforderlich" ist (abhängig von einem bestimmten Codefluss).
  • Das Laden ist synchron. Das heißt, wenn Sie mehrere requires haben, werden sie einzeln geladen und verarbeitet.

ES6-Importe:

  • Sie können benannte Importe verwenden, um selektiv nur die Teile zu laden, die Sie benötigen. Das kann Speicher sparen.
  • Der Import kann asynchron sein (und im aktuellen ES6-Modul-Loader ist dies tatsächlich der Fall) und eine etwas bessere Leistung erzielen.

Außerdem ist das Require-Modulsystem nicht standardbasiert. Es ist sehr unwahrscheinlich, dass dies zum Standard wird, wenn ES6-Module existieren. In Zukunft wird es native Unterstützung für ES6-Module in verschiedenen Implementierungen geben, was für die Leistung von Vorteil ist.

156
Amit

Die Hauptvorteile sind syntaktisch:

  • Deklarativere/kompaktere Syntax
  • ES6-Module machen UMD (Universal Module Definition) im Grunde genommen überflüssig - im Wesentlichen beseitigt sie die Kluft zwischen CommonJS und AMD (Server vs. Browser).

Es ist unwahrscheinlich, dass Sie mit ES6-Modulen Leistungsvorteile erzielen. Sie benötigen weiterhin eine zusätzliche Bibliothek, um die Module zu bündeln, auch wenn der Browser die ES6-Funktionen voll unterstützt.

39
snozza

Gibt es irgendwelche Leistungsvorteile, wenn man eins über das andere verwendet?

Die aktuelle Antwort lautet Nein, da keine der aktuellen Browser-Engines import/export aus dem ES6-Standard implementiert.

Einige Vergleichstabellen http://kangax.github.io/compat-table/es6/ berücksichtigen dies nicht. Wenn Sie also fast alle Grüns für Chrome sehen, seien Sie vorsichtig. Das Schlüsselwort import aus ES6 wurde nicht berücksichtigt.

Mit anderen Worten, aktuelle Browser-Engines, einschließlich V8, können neue JavaScript-Datei nicht über eine JavaScript-Direktive aus Haupt-JavaScript-Datei importieren.

(Möglicherweise sind wir nur noch ein paar Bugs entfernt oder Jahre entfernt, bis V8 dies gemäß der ES6-Spezifikation implementiert.)

Dieses Dokument ist das, was wir brauchen, und dieses Dokument ist das, was wir befolgen müssen.

Und der ES6-Standard besagte, dass die Modulabhängigkeiten vorhanden sein sollten, bevor wir das Modul wie in der Programmiersprache C lesen, in der wir (Header) .h -Dateien hatten.

Dies ist eine gute und gut getestete Struktur, und ich bin mir sicher, dass die Experten, die den ES6-Standard erstellt haben, dies im Hinterkopf hatten.

Dies ermöglicht es Webpack oder anderen Paket-Bundlern, das Bundle in einigen speziellen Fällen zu optimieren und einige nicht benötigte Abhängigkeiten vom Bundle zu reduzieren. Aber in Fällen, in denen wir perfekte Abhängigkeiten haben, wird dies niemals passieren.

Es wird einige Zeit dauern, bis die native Unterstützung für import/export aktiviert wird, und das Schlüsselwort require wird für längere Zeit nirgendwo verfügbar sein.

Was ist require?

Dies ist die node.js Methode zum Laden von Modulen. ( https://github.com/nodejs/node )

Der Knoten verwendet Methoden auf Systemebene, um Dateien zu lesen. Darauf verlassen Sie sich grundsätzlich, wenn Sie require verwenden. require endet in einem Systemaufruf wie uv_fs_open (abhängig vom Endsystem, Linux, Mac, Windows), um die JavaScript-Datei/das JavaScript-Modul zu laden.

Um dies zu überprüfen, versuchen Sie, Babel.js zu verwenden, und Sie werden feststellen, dass das Schlüsselwort import in require konvertiert wird.

enter image description here

32
prosti

Die Verwendung von ES6-Modulen kann nützlich sein, um Bäume zu schütteln. d.h. Webpack 2, Rollup (oder anderen Bundlern) ermöglichen, Codepfade zu identifizieren, die nicht verwendet/importiert werden, und es daher nicht in das resultierende Bundle zu schaffen. Dies kann die Dateigröße erheblich reduzieren, indem Sie Code eliminieren, den Sie nie benötigen. CommonJS ist jedoch standardmäßig im Lieferumfang enthalten, da Webpack et al. Keine Möglichkeit haben, zu wissen, ob er benötigt wird.

Dies erfolgt mithilfe einer statischen Analyse des Codepfads.

Zum Beispiel mit:

import { somePart } 'of/a/package';

... gibt dem Bundler einen Hinweis, dass package.anotherPart nicht erforderlich ist (wenn es nicht importiert wird, kann es nicht verwendet werden - oder?), damit es nicht die Mühe macht, es zu bündeln.

Um dies für Webpack 2 zu aktivieren, müssen Sie sicherstellen, dass Ihr Transpiler keine CommonJS-Module ausspuckt. Wenn Sie das es2015 -Plug-In mit babel verwenden, können Sie es in Ihrem .babelrc wie folgt deaktivieren:

{
  "presets": [
    ["es2015", { modules: false }],
  ]
}

Rollup und andere funktionieren möglicherweise anders - sehen Sie sich die Dokumente an, wenn Sie interessiert sind.

28
Lee Benson

Wenn es um asynchrones oder fauleres Laden geht, ist import () viel leistungsfähiger. Wenn wir die Komponente asynchron benötigen, verwenden wir import auf asynchrone Weise wie in const mit await.

const module = await import('./module.js');

Oder wenn Sie require() verwenden möchten,

const converter = require('./converter');

Was ist import() ist eigentlich asynchron in der Natur. Wie von neehar venugopal in ReactConf erwähnt, können Sie damit Reaktionskomponenten für die clientseitige Architektur dynamisch laden.

Auch beim Routing ist es viel besser. Dies ist eine Besonderheit, die bewirkt, dass das Netzwerkprotokoll einen erforderlichen Teil herunterlädt, wenn der Benutzer eine Verbindung zu einer bestimmten Website mit einer bestimmten Komponente herstellt. z.B. Die Anmeldeseite vor dem Dashboard hat nicht alle Komponenten des Dashboards heruntergeladen. Da die aktuell, d. H. Die Anmeldekomponente, benötigt wird, wird diese nur heruntergeladen.

Gleiches gilt für export: ES6 export ist genau das gleiche wie für CommonJS module.exports.

NOTE - Wenn Sie ein node.js-Projekt entwickeln, müssen Sie require() als Knoten wirft einen Ausnahmefehler als invalid token 'import', wenn Sie import verwenden. Daher unterstützt der Knoten keine Importanweisungen.

UPDATE - Wie von Dan Dascalescu vorgeschlagen: Seit Version 8.5.0 (veröffentlicht im September 2017) können Sie mit node --experimental-modules index.mjsimport ohne Babel. Sie können (und sollten) auch Ihre npm-Pakete als natives ESModule veröffentlichen, mit Abwärtskompatibilität für den alten require Weg.

Weitere Informationen zur Verwendung von asynchronen Importen finden Sie hier - https://www.youtube.com/watch?v=bb6RCrDaxhw

17
Meet Zaveri

Das Wichtigste, was Sie wissen müssen, ist, dass ES6-Module tatsächlich ein offizieller Standard sind, CommonJS-Module (Node.js) jedoch nicht.

Im Jahr 2019 werden ES6-Module von 84% der Browser unterstützt. Während Node.js sie hinter ein - experimental-modules -Flag setzt, gibt es auch ein praktisches Knotenpaket mit dem Namen esm , das die Integration reibungslos macht.

Ein weiteres Problem, mit dem Sie wahrscheinlich zwischen diesen Modulsystemen zu kämpfen haben, ist die Codestelle. Node.js geht davon aus, dass sich die Quelle in einem node_modules -Verzeichnis befindet, während die meisten ES6-Module in einer flachen Verzeichnisstruktur bereitgestellt werden. Diese sind nicht einfach zu vereinbaren, können aber durch Hacken Ihrer package.json -Datei mit Skripten vor und nach der Installation durchgeführt werden. Hier ist ein Beispiel isomorphes Modul und ein Artikel , das erklärt, wie es funktioniert.

7
isysd

Ich persönlich benutze Import, weil wir die erforderlichen Methoden importieren können, Mitglieder durch den Import.

import {foo, bar} from "dep";

Dateiname: dep.js

export foo function(){};
export const bar = 22

Der Kredit geht an Paul Shan. Mehr Infos .

6
chandoo