`export const` vs.` export default` di ES6

204

Saya mencoba menentukan apakah ada perbedaan besar antara keduanya, selain dapat mengimpor dengan export defaulthanya melakukan:

import myItem from 'myItem';

Dan menggunakan export constsaya bisa lakukan:

import { myItem } from 'myItem';

Saya bertanya-tanya apakah ada perbedaan dan / atau kasus penggunaan selain ini.

ajmajmajma
sumber
1
Menggunakan constakan membuat pengenal hanya baca. Jadi, dalam hal nilai-nilai primitif, Anda dapat menganggap itu tidak berubah. Perhatikan bahwa nilai itu sendiri tidak dapat diubah, sehingga objek, array, dll dapat diubah - hanya saja tidak ditugaskan kembali.
spmurrayzzz
4
@spmurrayzzz: FWIW, ikatan impor juga tidak berubah, sama seperti const.
Felix Kling
terima kasih atas klarifikasi @FelixKling, tidak tahu itu
spmurrayzzz
@ Feliksling: Dari luar, setidaknya. Meskipun mungkin tidak konstan, ekspor dapat diubah.
Bergi
@Bergi: benar, itu sebabnya saya katakan mengikat impor ;)
Felix Kling

Jawaban:

327

Ini adalah ekspor bernama vs ekspor default. export constadalah ekspor bernama yang mengekspor deklarasi atau deklarasi const.

Untuk menekankan: yang penting di sini adalah exportkata kunci seperti constyang digunakan untuk mendeklarasikan deklarasi konstitusi atau deklarasi. exportdapat juga diterapkan pada deklarasi lain seperti deklarasi kelas atau fungsi.

Ekspor Default ( export default)

Anda dapat memiliki satu ekspor standar per file. Ketika Anda mengimpor, Anda harus menentukan nama dan mengimpor seperti:

import MyDefaultExport from "./MyFileWithADefaultExport";

Anda dapat memberikan nama apa saja yang Anda suka.

Ekspor Bernama ( export)

Dengan ekspor bernama, Anda dapat memiliki beberapa ekspor bernama per file. Kemudian impor ekspor spesifik yang Anda inginkan ada dalam kurung:

// ex. importing multiple exports:
import { MyClass, MyOtherClass } from "./MyClass";
// ex. giving a named import a different name by using "as":
import { MyClass2 as MyClass2Alias } from "./MyClass2";

// use MyClass, MyOtherClass, and MyClass2Alias here

Atau dimungkinkan untuk menggunakan default bersama impor yang disebutkan dalam pernyataan yang sama:

import MyDefaultExport, { MyClass, MyOtherClass} from "./MyClass";

Impor Namespace

Anda juga dapat mengimpor semuanya dari file di objek:

import * as MyClasses from "./MyClass";
// use MyClasses.MyClass, MyClasses.MyOtherClass and MyClasses.default here

Catatan

  • Sintaksnya mendukung ekspor default sedikit lebih ringkas karena penggunaannya lebih umum ( Lihat diskusi di sini ).
  • Ekspor default sebenarnya adalah ekspor bernama dengan nama defaultsehingga Anda dapat mengimpornya dengan impor bernama:

    import { default as MyDefaultExport } from "./MyFileWithADefaultExport";
David Sherret
sumber
24

export defaultmempengaruhi sintaksis ketika mengimpor "barang" yang diekspor, ketika mengizinkan untuk mengimpor, apa pun yang telah diekspor, dengan memilih nama importitu sendiri, tidak peduli apa nama saat diekspor, hanya karena itu ditandai sebagai "default".

Case use berguna, yang saya suka (dan gunakan), memungkinkan untuk mengekspor fungsi anonim tanpa secara eksplisit harus menamainya, dan hanya ketika fungsi itu diimpor, itu harus diberi nama:


Contoh:

Ekspor 2 fungsi, satu adalah default:

export function divide( x ){
    return x / 2;
}

// only one 'default' function may be exported and the rest (above) must be named
export default function( x ){  // <---- declared as a default function
    return x * x;
}

Impor fungsi-fungsi di atas. Membuat nama untuk yang defaultsatu:

// The default function should be the first to import (and named whatever)
import square, {divide} from './module_1.js'; // I named the default "square" 

console.log( square(2), divide(2) ); // 4, 1

Ketika {}sintaks digunakan untuk mengimpor fungsi (atau variabel) itu berarti bahwa apa pun yang diimpor sudah bernama saat diekspor, jadi orang harus mengimpornya dengan nama yang sama persis , atau jika impor tidak akan berfungsi.


Contoh yang Salah:

  1. Fungsi default harus menjadi yang pertama diimpor

    import {divide}, square from './module_1.js
  2. divide_1tidak diekspor module_1.js, jadi tidak ada yang akan diimpor

    import {divide_1} from './module_1.js
  3. squaretidak diekspor module_1.js, karena {}memberitahu mesin untuk secara eksplisit mencari ekspor bernama saja.

    import {square} from './module_1.js
vsync
sumber
Itu tidak berarti bahwa itu mengekspor satu hal. Anda dapat memiliki beberapa nama dan satu default dalam modul yang sama. Default berarti persis seperti itu - ini adalah ekspor default jika Anda tidak menentukan nama saat mengimpor, yaitu import something fromalih-alih import { somethingNamed } from.
Andris
Saya juga belajar kata bahasa Inggris baru di sini: "Salah" +1 untuk itu
Yuval Levy
12

Catatan kecil: Harap perhatikan bahwa ketika Anda mengimpor dari ekspor default, penamaannya benar-benar independen. Ini sebenarnya berdampak pada refactoring.

Katakanlah Anda memiliki kelas Fooseperti ini dengan impor yang sesuai:

export default class Foo { }

//the name 'Foo' could be anything, since it's just an
//identifier for the default export
import Foo from './Foo'

Sekarang jika Anda mengubah Fookelas menjadi Bardan juga mengganti nama file, sebagian besar IDE TIDAK akan menyentuh impor Anda. Jadi, Anda akan berakhir dengan ini:

export default class Bar { }

//the name 'Foo' could be anything, since it's just an
//identifier for the default export.
import Foo from './Bar'

Khususnya dalam naskah, saya sangat menghargai ekspor bernama dan refactoring yang lebih andal. Perbedaannya hanyalah kurangnya defaultkata kunci dan kurung kurawal. Btw ini juga mencegah Anda membuat kesalahan ketik pada impor Anda karena Anda telah mengetikkan pemeriksaan sekarang.

export class Foo { }

//'Foo' needs to be the class name. The import will be refactored
//in case of a rename!
import { Foo } from './Foo'
Philipp Sumi
sumber
2
" 'Foo' perlu nama kelasnya. " - tidak! Anda dapat dengan mudah melakukan import { Foo as Anything } from …seperti yang dapat Anda lakukan import Anything from …dengan ekspor default.
Bergi
Anda dapat mengganti namanya dengan asbenar-benar bukan poin di komentar sumber itu. Terima kasih untuk downvote; p
Philipp Sumi
1
Saya tidak mengundurkan diri, namun saya tidak yakin apakah argumen itu meyakinkan. Saya tidak tahu apakah saya ingin IDE saya untuk mengganti nama semua impor ketika refactoring satu modul, itulah yang sebenarnya modularisasi adalah :-) Dan tampaknya lebih dari "masalah" IDE bukan alasan untuk memilih gaya ekspor …
Bergi
Saya setuju bahwa saya menggunakan ekspor bernama untuk kepentingan pengembang UX di sini - tapi kemudian, Anda bisa berpendapat bahwa semua jenis naskah adalah tentang itu. Saya sering refactor, dan mengingat bahwa saya biasanya memiliki satu kelas (dalam kasus saya: React Component) per file, saya benar-benar ingin impor mengikuti komponen yang diganti nama untuk tidak membuat putuskan sambungan. Tentu saja, ini mungkin atau mungkin tidak masuk akal tergantung pada pengembang individu.
Philipp Sumi
Saya menemukan artikel yang mengatakan hal yang sama. Mungkin posisi yang masuk akal bisa: kita harus menggunakan export defaultuntuk mengekspor objek utama proyek, khususnya dari paket npm (ini menggantikan a module.exports =). Tetapi, secara internal dalam suatu proyek, lebih baik menggunakan ekspor yang disebutkan saja.
Paleo
7

Dari dokumentasi :

Ekspor bernama berguna untuk mengekspor beberapa nilai. Selama impor, orang akan dapat menggunakan nama yang sama untuk merujuk ke nilai yang sesuai.

Mengenai ekspor standar, hanya ada satu ekspor standar per modul. Ekspor default dapat berupa fungsi, kelas, objek atau apa pun. Nilai ini harus dianggap sebagai nilai ekspor "utama" karena akan paling mudah untuk diimpor.

James Sumners
sumber
0

Ketika Anda meletakkan default, itu disebut ekspor standar. Anda hanya dapat memiliki satu ekspor default per file dan Anda dapat mengimpornya dalam file lain dengan nama apa pun yang Anda inginkan. Ketika Anda tidak menempatkan default, namanya bernama ekspor, Anda harus mengimpornya di file lain menggunakan nama yang sama dengan kurung kurawal di dalamnya.

Abdullah Danyal
sumber
0

Saya punya masalah bahwa browser tidak menggunakan es6.

Saya telah memperbaikinya dengan:

 <script type="module" src="index.js"></script>

Modul type memberi tahu browser untuk menggunakan ES6.

export const bla = [1,2,3];

import {bla} from './example.js';

Maka itu harus bekerja.

Marcel Zebrowski
sumber