używając nawiasów ze składnią importu javascript

115

Natknąłem się na bibliotekę javascript, która używa następującej składni do importowania bibliotek:

import React, { Component, PropTypes } from 'react';

Jaka jest różnica między powyższą metodą a następującą?

import React, Component, PropTypes from 'react';
lis
źródło
4
Odpowiedź znajduje się w dokumentacji
adeneo
4
Członkowie do zaimportowania z modułu są ujęci w nawiasy klamrowe
adeneo
1
Ha. Gdybyśmy wyeliminowali wszystkie sytuacje, w których można by prawdopodobnie odpowiedzieć na pytanie SO za pomocą „RTFM”, nawet Jon Skeet mógłby mieć mniej niż sześć cyfr. ; ^)
ruffin

Odpowiedzi:

174
import React, { Component, PropTypes } from 'react';

To mówi:

Importuj domyślny eksport spod 'react'nazwy Reacti importuj nazwane eksporty Componenti PropTypespod tymi samymi nazwami.

Łączy w sobie dwie popularne składnie, które prawdopodobnie widzieliście

import React from 'react';
import { Component, PropTypes } from 'react';

Pierwsza służy do importowania i nadawania nazwy domyślnemu eksportowi, a druga do importowania określonych nazwanych eksportów.

Z reguły większość modułów zapewnia pojedynczy, domyślny eksport lub listę nazwanych eksportów. Nieco rzadziej moduł udostępnia zarówno domyślny eksport, jak i nazwane eksporty. Jednak w przypadku, gdy istnieje jedna cecha, która jest najczęściej importowana, ale także dodatkowe funkcje podrzędne, prawidłowym projektem jest eksportowanie pierwszej jako domyślnej, a pozostałych jako nazwanych eksportów. W takich przypadkach użyjesz importskładni, do której się odnosisz.

Pozostałe odpowiedzi są gdzieś pomiędzy błędnymi a zagmatwanymi, być może dlatego, że dokumenty MDN w momencie zadawania tego pytania były błędne i zagmatwane. MDN pokazał przykład

import name from "module-name";

i mówi się, że namejest to „nazwa obiektu, który otrzyma zaimportowane wartości”. Ale to mylące i niepoprawne; po pierwsze jest tylko jedna wartość importu, która zostanie „odebrana” (dlaczego nie powiedzieć po prostu „przypisany do” lub „używany do odniesienia się do”) name, a wartość importu w tym przypadku jest domyślnym eksportem z modułu .

Innym sposobem wyjaśnienia tego jest zauważenie, że powyższy import jest dokładnie identyczny z

import { default as name } from "module-name";

a przykład PO jest dokładnie identyczny z

import { default as React, Component, PropTypes } from 'react';

W dalszej części dokumentacji MDN pokazano przykład

import MyModule, {foo, bar} from "my-module.js";

i twierdził, że to oznacza

Zaimportuj zawartość całego modułu, a niektóre z nich są również jawnie nazwane. To wstawia myModule(sic) foo, i bardo bieżącego zakresu. Zauważ, że fooi myModule.foosą takie same, jak są barimyModule.bar

To, co tu powiedział MDN i jakie inne odpowiedzi twierdzą na podstawie niewłaściwej dokumentacji MDN, jest całkowicie błędne i może opierać się na wcześniejszej wersji specyfikacji. To, co to właściwie robi, to

Importuj domyślny eksport modułu i kilka jawnie nazwanych eksportów. Te wkładki MyModule, foooraz barw bieżącym zakresie. Nazwy eksportu fooi niebar są dostępne za pośrednictwemMyModule , co jest domyślnym eksportem, a nie jakimś parasolem obejmującym wszystkie eksporty.

(Domyślnym eksportem modułu jest wartość eksportowana ze export defaultskładnią, która również może być export {foo as default}.)

Autorzy dokumentacji MDN mogli pomylić się z następującą formą:

import * as MyModule from 'my-module';

Spowoduje to zaimportowanie wszystkich eksportów z my-modulei udostępnienie ich pod nazwami, takimi jak MyModule.name. Domyślny eksport jest również dostępny jako MyModule.default, ponieważ domyślny eksport to nic innego jak inny nazwany eksport o nazwie default. W tej składni nie ma możliwości zaimportowania tylko podzbioru nazwanych eksportów, chociaż można zaimportować domyślny eksport, jeśli istnieje, razem ze wszystkimi nazwanymi eksportami, z

import myModuleDefault, * as myModule from 'my-module';

źródło
1
Babel akceptuje from '/path/to/my-module.js', chociaż ja osobiście używam from '/path/to/my-module'.
royhowie
5
Przy tak szczegółowym wyjaśnieniu należy również dodać, w jaki sposób są one eksportowane, aby można je było importować w ten sposób.
Caio Iglesias
37
import React, { Component, PropTypes } from 'react'

Spowoduje to pobranie wyeksportowanych { Component, PropTypes }członków z 'react'modułu i przypisanie ich odpowiednio do Componenti PropTypes. Reactbędzie równa defaulteksportowi modułu .

Jak zauważył torazaburo poniżej , to jest to samo co

import { default as React, Component, PropTypes } from 'react'

co jest skrótem dla

import { default as React, Component as Component, PropTypes as PropTypes} from 'react'

Oto kolejny przykład ( link do sedna ):

// myModule.js
export let a = true
export let b = 42
export let c = 'hello, world!'
// `d` is not exported alone
let d = 'some property only available from default'

// this uses the new object literal notation in es6
// {myVar} expands to { myVar : myVar }, provided myVar exists
// e.g., let test = 22; let o = {test}; `o` is then equal to { test : 22 }
export default { a, b, d }

// example1.js
import something from 'myModule'
console.log(something)
// this yields (note how `c` is not here):
/*
  {
    a : true,
    b : 42,
    d : 'some property only available from default'
  }
*/

// example2.js
import something, { c } from 'myModule'
console.log(something)  // same as above; the `default` export
console.log(c)          // c === 'hello, world!'

// example3.js
import { a, b, d, default as something } from 'myModule'
console.log(a)            // a === true
console.log(b)            // b === 42
console.log(d)            // d === undefined (we didn't export it individually)
console.log(something.d)  // something.d === 'some property...'

Przetestowałem drugi przykład z babel:

import test, test3, test2 from './app/lib/queries.js'
console.log(test, test3, test2)

i wystąpił błąd składni.

~/code/repo/tutoring $ babel-node test.js
/Users/royhowie/.node/lib/node_modules/babel/node_modules/babel-core/lib/babel/transformation/file/index.js:601
      throw err;
            ^
SyntaxError: /Users/royhowie/code/repo/tutoring/test.js: Unexpected token (1:13)
> 1 | import test, test3, test2 from './app/lib/queries.js'
    |              ^
  2 | 
  3 | console.log(test, test3, test2)
  4 | 

W celach informacyjnych możesz przeczytać nową importdokumentację z MDN. Jednak najwyraźniej wymaga przeglądu technicznego. Post na blogu dr Axela Rauschmayera jest teraz lepszym odniesieniem.

royhowie
źródło
1
Spowoduje to pobranie właściwości {Component, PropTypes} z eksportu w module „reaguj” i przypisanie ich do React. To jest niepoprawne. Przypisuje domyślny eksport React, a nazwane eksporty Componenti PropTypeszmienne o tej samej nazwie. Niestety, dokumenty MDN są błędne, o czym dowiedziałbyś się, gdybyś spróbował. Zobacz 2ality.com/2014/09/es6-modules-final.html . Ponadto składnia importu nie ma absolutnie nic wspólnego z przydziałem destrukturyzacji.
3
Jeśli chodzi o Twój komentarz dotyczący „nowej importdokumentacji”, przeglądając historię wersji tego artykułu w MDN, części, które cytujesz, nie zostały poprawione od czasu, gdy strona została napisana po raz pierwszy ponad rok temu, czyli w okresie, w którym składnia modułu była szybko się zmienia
1
@torazaburo Przepisałem odpowiedź, aby była dokładniejsza.
royhowie
@royhowie Dziękuję bardzo za ten przykład !! Dosłownie zaoszczędziłem kolejną godzinę bezmyślnego przeglądania ... Mam tylko jedno pytanie. W example3.jsdlaczego to wydrukować undefinedza console.log(d)? Ponieważ to zrobiłeś export default { a, b, d }, wyeksportowałeś go w formacie myModule.js.
CapturedTree
2
@ 1290 In myModule.jspamiętać, że a, bi cbyły wywożone indywidualnie. Oznacza to, że inny plik może je zaimportować bezpośrednio z import { a } from 'myModule'. Z drugiej strony djest dostępny tylko za pośrednictwem domyślnego eksportu, więc inny moduł może uzyskać do niego dostęp na dwa sposoby: import thisObjectContainsDefault from 'myModule'i uzyskać do niego dostęp przez thisObjectContainsDefault.dOR import { default as wrapperObject }i wrapperObject.d. Zaletą drugiego podejścia jest to, że możesz również pobrać elementy, które zostały wyeksportowane pojedynczo, jak widać na example3.js.
royhowie