Wann sollte ich geschweifte Klammern für den ES6-Import verwenden?

766

Es scheint offensichtlich zu sein, aber ich war etwas verwirrt darüber, wann geschweifte Klammern zum Importieren eines einzelnen Moduls in ES6 verwendet werden sollten. In dem React-Native-Projekt, an dem ich arbeite, habe ich beispielsweise die folgende Datei und ihren Inhalt:

initialState.js
var initialState = {
    todo: {
        todos: [
            {id: 1, task: 'Finish Coding', completed: false},
            {id: 2, task: 'Do Laundry', completed: false},
            {id: 2, task: 'Shopping Groceries', completed: false},
        ]
    }
};

export default initialState;

In der TodoReducer.js muss ich es ohne geschweifte Klammern importieren:

import initialState from './todoInitialState';

Wenn ich die initialStategeschweiften Klammern einschließe , wird für die folgende Codezeile der folgende Fehler angezeigt:

Eigenschaft todo von undefined kann nicht gelesen werden

TodoReducer.js:
export default function todos(state = initialState.todo, action) {
// ...
}

Ähnliche Fehler treten auch bei meinen Bauteilen mit den geschweiften Klammern auf. Ich habe mich gefragt, wann ich geschweifte Klammern für einen einzelnen Import verwenden soll, da Sie beim Importieren mehrerer Komponenten / Module diese natürlich in geschweifte Klammern einschließen müssen, die ich kenne.

Bearbeiten:

Der SO-Beitrag hier beantwortet meine Frage nicht, stattdessen frage ich, wann ich geschweifte Klammern zum Importieren eines einzelnen Moduls verwenden soll oder nicht , oder ich sollte niemals geschweifte Klammern zum Importieren eines einzelnen Moduls in ES6 verwenden (dies ist anscheinend nicht die Fall, wie ich gesehen habe, Einzelimport mit geschweiften Klammern erforderlich)

TonyGW
quelle
Mögliches Duplikat der Verwendung von Klammern mit Javascript-
Importsyntax
1
Nein, es ist anders. danke
TonyGW

Antworten:

2268

Dies ist ein Standardimport :

// B.js
import A from './A'

Es funktioniert nur, wenn Ader Standardexport :

// A.js
export default 42

In diesem Fall spielt es keine Rolle, welchen Namen Sie ihm beim Importieren zuweisen:

// B.js
import A from './A'
import MyA from './A'
import Something from './A'

Weil es immer in den Standard-Export von aufgelöst wird A.


Dies ist ein benannter Import mit dem NamenA :

import { A } from './A'

Es funktioniert nur, wenn es Aeinen benannten Export mit dem Namen enthältA :

export const A = 42

In diesem Fall ist der Name wichtig, da Sie eine bestimmte Sache anhand ihres Exportnamens importieren :

// B.js
import { A } from './A'
import { myA } from './A' // Doesn't work!
import { Something } from './A' // Doesn't work!

Um diese Arbeit zu machen, würden Sie einen hinzufügen entsprechenden Namen Export zu A:

// A.js
export const A = 42
export const myA = 43
export const Something = 44

Ein Modul kann nur einen Standardexport haben , aber so viele benannte Exporte, wie Sie möchten (null, eins, zwei oder viele). Sie können sie alle zusammen importieren:

// B.js
import A, { myA, Something } from './A'

Hier importieren wir die Standard - Export als A, und benannte Exporte genannt myAund Somethingsind.

// A.js
export default 42
export const myA = 43
export const Something = 44

Wir können ihnen beim Importieren auch alle unterschiedlichen Namen zuweisen:

// B.js
import X, { myA as myX, Something as XSomething } from './A'

Die Standardexporte werden in der Regel für alles verwendet, was Sie normalerweise vom Modul erwarten. Die genannten Exporte werden in der Regel für Dienstprogramme verwendet, die möglicherweise nützlich sind, aber nicht immer erforderlich sind. Es liegt jedoch an Ihnen, zu entscheiden, wie Dinge exportiert werden sollen: Beispielsweise hat ein Modul möglicherweise überhaupt keinen Standardexport.

Dies ist eine großartige Anleitung für ES-Module, in der der Unterschied zwischen Standard- und benannten Exporten erläutert wird.

Dan Abramov
quelle
4
Gibt es einen Nachteil, wenn ein Modul sowohl einzelne Exporte export const myA = 43; export const Something = 44;als auch einen hat export default { myA, Something }? Wenn Sie also importieren, können Sie entweder import A from './A';für alles im Modul, oder import { Something } from './A';so erhalten Sie nur einen Teil des Moduls
Michael
12
Es ist in Ordnung, aber es gibt bereits eine Syntax, um alle benannten Exporte in ein einziges Objekt zu packen : import * as AllTheThings.
Dan Abramov
82
Klar erklärt! Ich wünschte, ich könnte diese Antwort verdoppeln.
Willa
7
was ist damit- import 'firebase/storage';oder import 'rxjs/add/operator/map';. Was macht das eigentlich?
Kyw
9
@kyw: Dies führt das Modul aus, ignoriert jedoch den exportierten Wert. Nützlich für Nebenwirkungen.
Dan Abramov
84

Ich würde sagen, es gibt auch eine Sternnotation für das importerwähnenswerte ES6-Schlüsselwort.

Geben Sie hier die Bildbeschreibung ein

Wenn Sie versuchen, Log Mix zu konsolidieren:

import * as Mix from "./A";
console.log(Mix);

Sie erhalten:

Geben Sie hier die Bildbeschreibung ein

Wann sollte ich geschweifte Klammern für den ES6-Import verwenden?

Die Klammern sind golden, wenn Sie nur bestimmte Komponenten des Moduls benötigen, wodurch Bundler wie Webpack weniger Platz benötigen.

Prosti
quelle
4
Ihr Bild ist der perfekte Spickzettel für diese spezielle Antwort.
Rodrirokr
1
Sind import * as Mix from "./A";und import A as Mix from "./A";das gleiche?
Shafizadeh
40

Die Antwort von Dan Abramov oben erklärt die Standardexporte und benannten Exporte .

Welche verwenden?

Zitat von David Herman : ECMAScript 6 bevorzugt den Einzel- / Standardexportstil und bietet die süßeste Syntax für den Import des Standards. Der Import benannter Exporte kann und sollte etwas weniger präzise sein.

In TypeScript wird der benannte Export jedoch aufgrund von Refactoring bevorzugt. Wenn Sie beispielsweise eine Klasse standardmäßig exportieren und umbenennen, ändert sich der Klassenname nur in dieser Datei und nicht in den anderen Referenzen. Der Name der benannten Exportklasse wird in allen Referenzen umbenannt. Benannte Exporte werden auch für Versorgungsunternehmen bevorzugt.

Verwenden Sie insgesamt alles, was Sie bevorzugen.

Zusätzlich

Der Standardexport ist eigentlich ein benannter Export mit dem Standardnamen, sodass der Standardexport wie folgt importiert werden kann:

import {default as Sample} from '../Sample.js';
Deepak Sharma
quelle
2
Die AdditionalZeile ist eine gute Information. import A from './A'macht keinen Sinn, wenn Sie exportieren, ohne einen Namen wie zu definieren export default 42.
PGT
8
Bitte achten Sie darauf, das Zitat von David Herman nicht falsch zu interpretieren. Dies bedeutet nicht " Es wird bevorzugt, in ES6 immer Einzel- / Standardexporte zu verwenden ", sondern " Da Einzelexporte so häufig sind, unterstützt ES6 die Standardeinstellungen am besten und wir haben ihnen die süßeste Syntax gegeben ".
Bergi
15

Wenn Sie sich importnur Syntaxzucker für Knotenmodule, Objekte und Destrukturierung vorstellen, finde ich das ziemlich intuitiv.

// bar.js
module = {};

module.exports = { 
  functionA: () => {},
  functionB: ()=> {}
};

 // really all that is is this:
 var module = { 
   exports: {
      functionA, functionB
   }
  };

// then, over in foo.js

// the whole exported object: 
var fump = require('./bar.js'); //= { functionA, functionB }
// or
import fump from './bar' // same thing, object functionA and functionB props


// just one prop of the object
var fump = require('./bar.js').functionA;

// same as this, right?
var fump = { functionA, functionB }.functionA;

// and if we use es6 destructuring: 
var { functionA } =  { functionA, functionB };
// we get same result

// so, in import syntax:
import { functionA } from './bar';
Brandon
quelle
9

Um die Verwendung von geschweiften Klammern in importAnweisungen zu verstehen, müssen Sie zunächst das in ES6 eingeführte Konzept der Zerstörung verstehen

  1. Objektzerstörung

    var bodyBuilder = {
      firstname: 'Kai',
      lastname: 'Greene',
      nickname: 'The Predator'
    };
    
    var {firstname, lastname} = bodyBuilder;
    console.log(firstname, lastname); //Kai Greene
    
    firstname = 'Morgan';
    lastname = 'Aste';
    
    console.log(firstname, lastname); // Morgan Aste
  2. Array-Destrukturierung

    var [firstGame] = ['Gran Turismo', 'Burnout', 'GTA'];
    
    console.log(firstGame); // Gran Turismo

    Listenabgleich verwenden

      var [,secondGame] = ['Gran Turismo', 'Burnout', 'GTA'];
      console.log(secondGame); // Burnout

    Verwenden des Spread-Operators

    var [firstGame, ...rest] = ['Gran Turismo', 'Burnout', 'GTA'];
    console.log(firstGame);// Gran Turismo
    console.log(rest);// ['Burnout', 'GTA'];

Nachdem wir das aus dem Weg geräumt haben , können Sie in ES6 mehrere Module exportieren. Sie können dann die Objektzerstörung wie unten verwenden

Nehmen wir an, Sie haben ein Modul namens module.js

    export const printFirstname(firstname) => console.log(firstname);
    export const printLastname(lastname) => console.log(lastname);

Sie möchten die exportierten Funktionen in importieren index.js.

    import {printFirstname, printLastname} from './module.js'

    printFirstname('Taylor');
    printLastname('Swift');

Sie können auch verschiedene Variablennamen verwenden

    import {printFirstname as pFname, printLastname as pLname} from './module.js'

    pFname('Taylor');
    pLanme('Swift');
theTypan
quelle
Da Sie Vergleiche zur Destrukturierung zeigen, würde ich Ihrem letzten Kommentar den entsprechenden Destrukturierungsvergleich hinzufügen: import {printFirstname as pFname, printLastname as pLname} from './module.js'entspricht:var foo = {printFirstname: 'p_f_n', printLastname: 'p_l_n'}; var { printFirstname:pFname, printLastname: pLname } = foo; pFname('Taylor'); pLname('Swift');
Adam Moisa
Bodybuilding-Fan?
Tushar Pandey
@ TusharPandey Ich bin ein
Bodybuilder
1
Ich denke, in jeder Erklärung zum Importieren und wann man Curlys verwendet, anstatt sie nicht zu verwenden, wenn man die Zerstörung von Objekten nicht erwähnt, gibt man wirklich nicht die beste Erklärung. Als ich etwas über Destrukturierung gelernt hatte, dachte ich nie mehr darüber nach, warum ich das Curly mehr benutze. Es machte nur intuitiv Sinn.
Eric Bishard
6

Zusammenfassung ES6 :

Exporte:

Sie haben 2 Arten von Exporten:

  1. Benannte Exporte
  2. Standardexporte, maximal 1 pro Modul

Syntax:

// Module A
export const importantData_1 = 1;
export const importantData_2 = 2;
export default function foo () {}

Importe:

Die Art des Exports (dh benannte oder Standardexporte) beeinflusst, wie etwas importiert wird:

  1. Für einen benannten Export müssen geschweifte Klammern und der genaue Name verwendet werden als Deklaration (dh Variable, Funktion oder Klasse) verwendet werden, die exportiert wurde.
  2. Für einen Standardexport können wir den Namen wählen.

Syntax:

// Module B, imports from module A which is located in the same directory

import { importantData_1 , importantData_2  } from './A';  // for our named imports

// syntax single named import: 
// import { importantData_1 } 

// for our default export (foo), the name choice is arbitrary
import ourFunction from './A';   

Interessante Dinge:

  1. Verwenden Sie eine durch Kommas getrennte Liste in geschweiften Klammern mit dem übereinstimmenden Namen des Exports für den benannten Export.
  2. Verwenden Sie für einen Standardexport einen Namen Ihrer Wahl ohne geschweifte Klammern.

Aliase:

Wann immer Sie einen benannten Import umbenennen möchten, ist dies über Aliase möglich . Die Syntax hierfür lautet wie folgt:

import { importantData_1 as myData } from './A';

Jetzt haben wir importiert, importantData_1 aber der Bezeichner ist myDatastatt importantData_1.

Willem van der Veen
quelle
5

Wenn Sie eine Funktion exportieren, müssen Sie normalerweise die {} verwenden

if you have export const x 

Sie nutzen import {x} from ''

if you use export default const x 

Sie verwenden müssen , um import X from '' hier Sie X, was auch immer ändern können Variable , die Sie wollen

Jadlmir
quelle
4

Die geschweiften Klammern ({}) werden zum Importieren benannter Bindungen verwendet, und das Konzept dahinter ist die Destrukturierungszuweisung

Eine einfache Demonstration der Funktionsweise der Importanweisung anhand eines Beispiels finden Sie in meiner eigenen Antwort auf eine ähnliche Frage unter Wann verwenden wir '{}' bei Javascript-Importen?

samuelj90
quelle
1
Sie bekommen definitiv meine Stimme für die beste kurze Antwort!
Eric Bishard
0

Die geschweiften Klammern werden nur für den Import verwendet, wenn der Export benannt ist. Wenn der Export standardmäßig ist, werden geschweifte Klammern nicht für den Import verwendet.

Abhishek Kumar
quelle
0

Für einen Standardexport verwenden wir beim Importieren nicht {}.

z.B

player.js

export default vx;

index.js

import vx from './player';

index.js Geben Sie hier die Bildbeschreibung ein

player.js Geben Sie hier die Bildbeschreibung ein

Wenn wir alles importieren möchten, was wir exportieren, verwenden wir * Geben Sie hier die Bildbeschreibung ein

user260778
quelle