menggunakan tanda kurung dengan sintaks impor javascript

115

Saya menemukan perpustakaan javascript yang menggunakan sintaks berikut untuk mengimpor perpustakaan:

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

Apa perbedaan antara metode di atas dan yang berikut ini?

import React, Component, PropTypes from 'react';
rubah
sumber
4
Jawabannya ada dalam dokumentasi
adeneo
4
Anggota yang akan diimpor dari modul diapit oleh kurung kurawal
adeneo
1
Ha. Jika kita mengeliminasi semua waktu orang bisa menjawab pertanyaan SO dengan "RTFM", bahkan Jon Skeet mungkin memiliki kurang dari enam angka. ; ^)
ruffin

Jawaban:

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

Ini mengatakan:

Impor ekspor default dari 'react'bawah nama Reactdan impor ekspor bernamaComponent dan PropTypesdengan nama yang sama.

Ini menggabungkan dua sintaks umum yang mungkin pernah Anda lihat

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

Yang pertama digunakan untuk mengimpor dan memberi nama ekspor default, yang kedua untuk mengimpor ekspor bernama yang ditentukan.

Sebagai aturan umum, sebagian besar modul akan menyediakan ekspor default tunggal, atau daftar ekspor bernama. Ini agak kurang biasa bagi modul untuk menyediakan ekspor default dan ekspor bernama. Namun, dalam kasus di mana ada satu fitur yang paling sering diimpor, tetapi juga sub-fitur tambahan, itu adalah desain yang valid untuk mengekspor yang pertama sebagai default, dan yang tersisa sebagai ekspor bernama. Dalam kasus seperti itu, Anda akan menggunakan importsintaks yang Anda rujuk.

Jawaban lainnya mungkin salah dan membingungkan, mungkin karena dokumen MDN pada saat pertanyaan ini diajukan salah dan membingungkan. MDN menunjukkan contohnya

import name from "module-name";

dan kata nameadalah "nama objek yang akan menerima nilai yang diimpor." Tapi itu menyesatkan dan tidak benar; pertama-tama, hanya ada satu nilai impor, yang akan "diterima" (mengapa tidak hanya mengatakan "ditugaskan ke", atau "digunakan untuk merujuk ke") name, dan nilai impor dalam hal ini adalah ekspor default dari modul .

Cara lain untuk menjelaskan hal ini adalah dengan memperhatikan bahwa impor di atas persis sama dengan

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

dan contoh OP persis sama dengan

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

Dokumentasi MDN selanjutnya menunjukkan contohnya

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

dan mengklaim bahwa itu berarti

Impor seluruh konten modul, dengan beberapa juga diberi nama secara eksplisit. Ini menyisipkan myModule(sic) foo,, dan barke dalam cakupan saat ini. Perhatikan bahwa foodan myModule.fooadalah sama, as are bardanmyModule.bar

Apa yang dikatakan MDN di sini, dan jawaban lain apa yang diklaim berdasarkan dokumentasi MDN yang salah, benar-benar salah, dan mungkin didasarkan pada versi spesifikasi sebelumnya. Apa yang sebenarnya dilakukannya adalah

Impor ekspor modul default dan beberapa ekspor dengan nama yang jelas. Ini menyisipkan MyModule,, foodan barke dalam cakupan saat ini. Nama-nama ekspor foodan baryang tidak dapat diakses melaluiMyModule , yang merupakan standar ekspor, tidak beberapa payung yang mencakup semua ekspor.

(Ekspor modul default adalah nilai yang diekspor dengan export defaultsintaks, yang juga bisa jadi export {foo as default}.)

Penulis dokumentasi MDN mungkin bingung dengan formulir berikut:

import * as MyModule from 'my-module';

Ini mengimpor semua ekspor dari my-module, dan membuatnya dapat diakses dengan nama seperti MyModule.name. Ekspor default juga dapat diakses sebagai MyModule.default, karena ekspor default sebenarnya tidak lebih dari ekspor bernama lain dengan nama default. Dalam sintaks ini, tidak ada cara untuk mengimpor hanya subset dari ekspor bernama, meskipun seseorang dapat mengimpor ekspor default, jika ada, bersama dengan semua ekspor bernama, dengan

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

sumber
1
Babel menerima from '/path/to/my-module.js', meskipun saya pribadi menggunakan from '/path/to/my-module'.
royhowie
5
Dengan penjelasan sedetail itu sebaiknya Anda juga menambahkan bagaimana mereka diekspor agar bisa diimpor seperti itu.
Caio Iglesias
37
import React, { Component, PropTypes } from 'react'

Ini akan mengambil { Component, PropTypes }anggota yang diekspor dari 'react'modul dan menetapkannya ke Componentdan PropTypes, masing-masing. Reactakan sama dengan defaultekspor modul .

Sebagaimana dicatat oleh torazaburo di bawah ini, ini sama dengan

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

yang merupakan singkatan dari

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

Berikut contoh lain ( tautan ke inti ):

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

Saya menguji contoh kedua dengan babel:

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

dan mendapat kesalahan sintaks.

~/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 | 

Sebagai referensi, Anda dapat membaca importdokumentasi baru dari MDN. Namun, hal itu tampaknya membutuhkan tinjauan teknis. Posting blog Dr. Axel Rauschmayer adalah referensi yang lebih baik untuk saat ini.

royhowie
sumber
1
Ini akan mengambil properti {Component, PropTypes} dari ekspor di modul 'react' dan menugaskannya ke React. Ini salah Ini menetapkan ekspor default ke React, dan ekspor bernama Componentdan PropTypeske variabel dengan nama yang sama. Sayangnya, dokumen MDN salah, karena Anda akan mengetahuinya jika mencobanya. Lihat 2ality.com/2014/09/es6-modules-final.html . Selain itu, sintaks impor sama sekali tidak ada hubungannya dengan tugas penghancuran.
3
Berkenaan dengan komentar Anda tentang " importdokumentasi baru`, meninjau riwayat revisi artikel MDN tersebut, bagian yang Anda kutip belum direvisi sejak halaman pertama kali ditulis lebih dari setahun yang lalu, periode di mana sintaks modul berubah dengan cepat.
1
@torazaburo Saya menulis ulang jawaban saya agar lebih akurat.
royhowie
@royhowie Terima kasih banyak atas contoh ini !! Benar-benar menghemat satu jam lagi untuk menjelajahi sekitar tanpa berpikir ... Saya hanya punya satu pertanyaan. Dalam example3.jsmengapa itu mencetak undefineduntuk console.log(d)? Sejak Anda melakukannya, export default { a, b, d }Anda mengekspornya ke dalam myModule.js.
CapturedTree
2
@ 1290 Dalam myModule.js, catatan itu a, bdan cdiekspor secara individual. Ini berarti file lain dapat mengimpornya secara langsung dengan import { a } from 'myModule'. Di sisi lain, dhanya tersedia melalui ekspor default, sehingga modul lain dapat mengaksesnya dengan dua cara: import thisObjectContainsDefault from 'myModule'dan mengaksesnya melalui thisObjectContainsDefault.dOR import { default as wrapperObject }dan wrapperObject.d. Manfaat dari pendekatan kedua adalah Anda juga dapat mengambil item yang diekspor secara individual, seperti yang dapat dilihat di example3.js.
royhowie