Frage Was ist der Unterschied zwischen mit und ohne geschweifte Klammernotation in Export- / Importanweisungen?


Ich bin neu in ES6 und ein bisschen verwirrt mit der Art, wie Klassen exportiert und importiert werden. Es scheint, dass viele verschiedene Notationen gültig sind, aber anders funktionieren.

Ich schrieb eine Klasse wie diese src/web-api.js:

class WebApi {
    // ...
}

export { WebApi };

Was ich importiere mit:

import { WebApi } from './src/web-api.js'

Das funktioniert gut, aber vorher habe ich dasselbe ohne geschweifte Klammern versucht und es hat nicht funktioniert:

export WebApi; // Tells me '{' expected

import WebApi from './src/web-api.js'; // No syntax error but WebApi is undefined

Obwohl auf der MDN-Dokumentation für den Export, die Notation export expression; scheint gültig zu sein.

Genauso wird React in meine Anwendungsdatei importiert:

import React, { Component } from 'react';

Warum ist eine Klasse mit und eine andere ohne geschweifte Klammern? Wie kann ich im Allgemeinen feststellen, wann geschweifte Klammern verwendet und nicht verwendet werden sollen?


5
2018-05-06 17:07


Ursprung


Antworten:


ES6 bietet an viele Möglichkeiten, Module durch Import / Export zu verwalten. Aber es gibt im Wesentlichen zwei Hauptstrategien:

  1. Standard exportieren / importieren mit export default und import module from './module'
  2. Mehrere Exporte / Importe mit export und import {member} from './module' oder import * as module from './module'

(Mischen von beiden ist möglich, aber nicht empfohlen.)


Modul zum Exportieren / Importieren

function foo() {
  console.log('Foo');
}

function bar() {
  console.log('Bar');
}

Strategie # 1: Standard Export / Import

Exportieren (module.js)

function foo() {
  console.log('Foo');
}

function bar() {
  console.log('Bar');
}

export default {foo, bar};

/*
  {foo, bar} is just an ES6 object literal that could be written like so:

  export default {
    foo: foo,
    bar: bar
  };

  It is the legacy of the "Revealing Module pattern"...
*/

Importieren (main.js)

import module from './module';

module.foo(); // Foo
module.bar(); // Bar

Strategie # 2: Mehrere Exporte / Importe

Exportieren (module.js)

export function foo() {
  console.log('Foo');
}

export function bar() {
  console.log('Bar');
}

Importieren (main.js)

import {foo, bar} from './module';

foo(); // Foo
bar(); // Bar

/*
  This is valid too:

  import * as module from './module';

  module.foo(); // Foo
  module.bar(); // Bar
*/

Wie ich bereits sagte, ES6-Module sind viel komplexer als das. Für weitere Informationen empfehle ich Ihnen zu lesen ES6 erkunden durch Dr. Axel Rauschmayerbesonders dieses Kapitel: http://exploringjs.com/es6/ch_modules.html.


6
2018-05-06 18:31



Die Zahnspange ist nur syntaktischer Zucker. Es wird den Variablennamen als Objektschlüssel verwenden, zum Beispiel:

const a = 1;
const test = {a}; // same as {a: 1};

Es kann auch verwendet werden, um das Objekt durch seinen Variablennamen zu destrukturieren. Es prüft, ob das Objekt Eigenschaften mit dem gleichen Wert wie der Variablenname hat und gibt dann einen Wert aus, wenn einer gefunden wird:

const test = {a: 1};
const {a} = test; // a = 1

In Modulen ist der allgemeine Anwendungsfall, dass beim Importieren normalerweise Klammern vorhanden sind, da Module als importiert werden MODULE.function oder MODULE.class. Es wäre intuitiver, zuerst die Exporte zu betrachten:

Für den Export wird der zuvor erwähnte syntaktische Zucker verwendet - Sie exportieren ihn als Objekt. Wenn Sie das tun export { WebApi }; was du wirklich tust ist export {WebApi: WebApi}. Dies macht es einfacher, auf Dinge zuzugreifen, da Sie jetzt einfach 'MODULE.WebApi' verwenden können, um auf die Klasse zuzugreifen, anstatt den Namespace unnötigerweise zu verschmutzen. Dies ist auch für alle Exporte erforderlich!

Wenn Sie mit Importen fortfahren, zerstückelt das, was Sie in den import-Anweisungen machen, das Modulobjekt und wählt eine Eigenschaft aus, die in eine Variable mit demselben Namen gespeichert werden soll. In deinem Fall, wenn du es tust import {WebApi} from './src/web-api.js' du würdest so etwas tun import WebApi = web-api.js['WebApi'] from './src/web-api.js' (Dies ist keine gültige Syntax, sondern nur um Ihnen zu zeigen, was es im Hintergrund macht). Dies ist auch erforderlich, um Modulfunktionen / -klassen ordnungsgemäß zu importieren. Es gibt auch die Möglichkeit, das gesamte Modul zu importieren, genau wie NodeJS: import * as ModuleName from './src/module.js'. Dadurch werden alle exportierten Funktionen / Klassen in das ModuleName-Objekt eingefügt, sodass es wie ein normales Modul behandelt werden kann.

Wenn ein Modul jedoch eine default Export, Klammern werden für den Import und Export nicht benötigt. Zum Beispiel hat wahrscheinlich reagieren export default React in seinen Dateien - deshalb braucht man keine Klammern um sie herum zu haben import React from 'react'

Hoffe, ich war nicht zu verwirrend und lassen Sie mich wissen, wenn ich etwas klären kann!


1
2018-05-06 17:24