Kiedy należy używać nawiasów klamrowych do importowania ES6?

763

Wydaje się to oczywiste, ale byłem trochę zdezorientowany, kiedy używać nawiasów klamrowych do importowania jednego modułu w ES6. Na przykład w projekcie React-Native, nad którym pracuję, mam następujący plik i jego zawartość:

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;

W TodoReducer.js muszę go zaimportować bez nawiasów klamrowych:

import initialState from './todoInitialState';

Jeśli dołączę initialStatenawiasy klamrowe, pojawia się następujący błąd dla następującego wiersza kodu:

Nie można odczytać todo właściwości niezdefiniowanej

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

Podobne błędy zdarzają się również w moich komponentach z nawiasami klamrowymi. Zastanawiałem się, kiedy powinienem użyć nawiasów klamrowych do pojedynczego importu, ponieważ oczywiście podczas importowania wielu komponentów / modułów musisz je zamknąć w nawiasach klamrowych, które znam.

Edytować:

Post SO tutaj tutaj nie odpowiada na moje pytanie, zamiast tego pytam, kiedy powinienem lub nie powinienem używać nawiasów klamrowych do importowania pojedynczego modułu, lub nigdy nie powinienem używać nawiasów klamrowych do importowania pojedynczego modułu w ES6 (najwyraźniej nie jest to przypadek, ponieważ widziałem pojedynczy import z wymaganymi nawiasami klamrowymi)

TonyGW
źródło
1
nie, jest inaczej. dzięki
TonyGW

Odpowiedzi:

2261

To jest domyślny import :

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

Działa tylko wtedy, gdy Ama domyślny eksport :

// A.js
export default 42

W takim przypadku nie ma znaczenia, jaką nazwę mu nadasz podczas importowania:

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

Bo zawsze będzie rozwiązać, aby cokolwiek jest domyślny eksport z A.


Jest to nazwany import o nazwieA :

import { A } from './A'

Działa tylko wtedy, gdy Azawiera nazwany eksport o nazwieA :

export const A = 42

W tym przypadku nazwa ma znaczenie, ponieważ importujesz konkretną rzecz według nazwy eksportu :

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

Aby te działały, należy dodać odpowiedni nazwany eksport do A:

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

Moduł może mieć tylko jeden domyślny eksport , ale tyle nazwanych eksportów, ile chcesz (zero, jeden, dwa lub wiele). Możesz zaimportować je wszystkie razem:

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

Tutaj import eksport jako domyślny A, i nazwał eksportu nazwie myAi Something, odpowiednio.

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

Możemy również przypisać im wszystkie różne nazwy podczas importowania:

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

Domyślny eksport jest zwykle używany do wszystkiego, czego normalnie oczekujesz od modułu. Nazwane eksporty są zwykle używane do narzędzi, które mogą być przydatne, ale nie zawsze są konieczne. Jednak to Ty decydujesz, jak eksportować rzeczy: na przykład moduł może w ogóle nie mieć domyślnego eksportu.

Jest to świetny przewodnik po modułach ES, wyjaśniający różnicę między eksportem domyślnym a nazwanym.

Dan Abramov
źródło
4
Czy jest jakiś minus posiadania modułu z indywidualnym eksportem, export const myA = 43; export const Something = 44;a także z export default { myA, Something }? Więc kiedy importujesz, możesz albo import A from './A';dla wszystkiego w module, albo import { Something } from './A';też dostajesz tylko część modułu
Michael
12
To jest w porządku, ale nie ma już składnia do zgrywania wszystkich wymienionych eksportu do pojedynczego obiektu import * as AllTheThings.
Dan Abramov
82
Wyjaśnione! Chciałbym móc podwoić głosowanie w tej odpowiedzi.
Willa
7
co z tym- import 'firebase/storage';lub import 'rxjs/add/operator/map';. Co to właściwie robi?
kyw
9
@kyw: Wykonuje moduł, ale ignoruje eksportowaną wartość. Przydatny w przypadku skutków ubocznych.
Dan Abramov
123

TL; DR : Nawiasy klamrowe są używane, jeśli chcesz zaimportować niestandardowy eksport.

Zobacz więcej odpowiedzi Dana Abramova powyżej.

Daniel Schmidt
źródło
7
Co przyczynia się do tej odpowiedzi oprócz podania innej odpowiedzi?
franksands
6
Wysyłam go wcześniej, a potem edytuję, przepraszam za niedogodności
Daniel Schmidt
Nie próbowałem być palantem, próbowałem to sformułować w najbardziej uprzejmy sposób. Właśnie zastanawiałem się, dlaczego ta odpowiedź była tutaj.
franksands
2
Przypuszczam, że to kwestia opinii, ale uważam to za bardzo pomocne. Przejrzałem powyższą odpowiedź i to potwierdziło to, co, jak sądzę, próbowało się komunikować.
MORCHARD
84

Powiedziałbym, że istnieje także notacja importoznaczona gwiazdką dla słowa kluczowego ES6.

wprowadź opis zdjęcia tutaj

Jeśli spróbujesz konsolować log Mix:

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

Dostaniesz:

wprowadź opis zdjęcia tutaj

Kiedy należy używać nawiasów klamrowych do importowania ES6?

Wsporniki są złote, gdy potrzebujesz tylko określonych komponentów z modułu, co sprawia, że ​​zajmują mniej miejsca dla pakujących, takich jak webpack.

prosti
źródło
4
Twój obraz jest idealnym ściągaczem dla tej konkretnej odpowiedzi.
Rodrirokr
1
import * as Mix from "./A";i import A as Mix from "./A";takie same?
Shafizadeh
40

Powyższa odpowiedź Dana Abramova wyjaśnia domyślny eksport i nazwany eksport .

Którego użyć?

Cytując Davida Hermana : ECMAScript 6 faworyzuje pojedynczy / domyślny styl eksportu i daje najsłodszą składnię do importowania domyślnego. Import nazwanych eksportów może, a nawet powinien być nieco mniej zwięzły.

Jednak w TypeScript preferowany jest eksport o nazwie ze względu na refaktoryzację. Przykład: jeśli domyślnie wyeksportujesz klasę i zmienisz jej nazwę, nazwa klasy zmieni się tylko w tym pliku, a nie w innych referencjach, a nazwa klasy eksportu o nazwie zostanie zmieniona we wszystkich referencjach. Eksport nazwany jest również preferowany w przypadku narzędzi.

Ogólnie używaj, co chcesz.

Dodatkowy

Domyślny eksport jest tak naprawdę nazwanym eksportem o nazwie default, więc domyślny eksport można zaimportować jako:

import {default as Sample} from '../Sample.js';
Deepak Sharma
źródło
2
AdditionalLinia jest dobra informacja. import A from './A'nie ma sensu, jeśli eksportujesz bez zdefiniowania nazwy takiej jak export default 42.
PGT
8
Proszę nie dopuścić do błędnej interpretacji cytatu Davida Hermana. Nie oznacza to: „ Zaleca się, aby zawsze używać eksportu pojedynczego / domyślnego w ES6 ”, ale raczej „ Ponieważ pojedynczy eksport jest tak powszechny, ES6 najlepiej obsługuje ustawienia domyślne i nadaliśmy im najsłodszą składnię ”.
Bergi
15

Jeśli myślisz o importcukrze składniowym dla modułów węzłów, obiektów i destrukcji, uważam, że jest to dość intuicyjne.

// 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
źródło
9

Aby zrozumieć użycie nawiasów klamrowych w importinstrukcjach, najpierw musisz zrozumieć koncepcję niszczenia wprowadzoną w ES6

  1. Niszczenie obiektów

    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. Niszczenie tablic

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

    Korzystanie z dopasowywania listy

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

    Korzystanie z operatora rozrzucania

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

Teraz, gdy mamy to za sobą, w ES6 możesz eksportować wiele modułów. Następnie możesz skorzystać z funkcji niszczenia obiektów, jak poniżej

Załóżmy, że masz moduł o nazwie module.js

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

Chcesz zaimportować wyeksportowane funkcje do index.js;

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

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

Możesz także użyć różnych nazw zmiennych

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

    pFname('Taylor');
    pLanme('Swift');
theTypan
źródło
Ponieważ pokazuje Pan porównania do destrukcji, do ostatniego komentarza dodam równoważne porównanie destrukcji: import {printFirstname as pFname, printLastname as pLname} from './module.js'jest równoważne z:var foo = {printFirstname: 'p_f_n', printLastname: 'p_l_n'}; var { printFirstname:pFname, printLastname: pLname } = foo; pFname('Taylor'); pLname('Swift');
Adam Moisa
fan kulturystyki?
Tushar Pandey,
@TusharPandey Jestem
kulturystą
1
Myślę, że w każdym wyjaśnieniu importowania i kiedy używać curlys zamiast ich nie używać, jeśli nie wspominasz o niszczeniu obiektów, naprawdę nie podajesz najlepszego wyjaśnienia. Kiedy dowiedziałem się o destrukcji, nigdy nie myślałem o tym, dlaczego używam tego kręcenia, po prostu intuicyjnie miało sens.
Eric Bishard,
6

ES6Moduły podsumowujące :

eksport:

Masz 2 rodzaje eksportu:

  1. Nazwany eksport
  2. Domyślny eksport, maksymalnie 1 na moduł

Składnia:

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

Import:

Rodzaj eksportu (tj nazwie lub eksport domyślne) wpływa Jak importować coś:

  1. W przypadku nazwanego eksportu musimy użyć nawiasów klamrowych i dokładnej nazwy jako deklaracji (tj. Zmiennej, funkcji lub klasy), która została wyeksportowana.
  2. W przypadku domyślnego eksportu możemy wybrać nazwę.

Składnia:

// 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';   

Ciekawe rzeczy:

  1. Użyj rozdzielonej przecinkami listy w nawiasach klamrowych z pasującą nazwą eksportu dla nazwanego eksportu.
  2. Użyj domyślnej nazwy bez nawiasów klamrowych do domyślnego eksportu.

Skróty:

Ilekroć chcesz zmienić nazwę nazwanego importu, jest to możliwe poprzez aliasy . Składnia tego jest następująca:

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

Teraz zaimportowaliśmy, importantData_1 ale identyfikator jest myDatazamiast importantData_1.

Willem van der Veen
źródło
5

zwykle podczas eksportowania funkcji musisz użyć {}

if you have export const x 

używasz import {x} from ''

if you use export default const x 

musisz użyć import X from '' tutaj, możesz zmienić X na dowolną zmienną, którą chcesz

jadlmir
źródło
4

Nawiasy klamrowe ({}) są używane do importowania nazwanych powiązań, a ich podstawą jest przypisanie destrukcyjne

Prostą demonstrację działania instrukcji importu na przykładzie można znaleźć we własnej odpowiedzi na podobne pytanie w Kiedy używamy „{}” w imporcie javascript?

samuelj90
źródło
1
zdecydowanie dostajesz mój głos na najlepszą krótką odpowiedź!
Eric Bishard,
0

Nawiasy klamrowe są używane tylko do importu, gdy nazwany jest eksport. Jeśli eksport jest domyślny, wówczas do importu nie są używane nawiasy klamrowe.

Abhishek Kumar
źródło
0

Do domyślnego eksportu nie używamy {} podczas importu.

na przykład

player.js

export default vx;

index.js

import vx from './player';

index.js wprowadź opis zdjęcia tutaj

player.js wprowadź opis zdjęcia tutaj

Jeśli chcemy zaimportować wszystko, co eksportujemy, używamy * wprowadź opis zdjęcia tutaj

użytkownik260778
źródło