Ekspor skrip vs. ekspor default

273

Apa perbedaan dalam Script antara exportdan default export. Dalam semua tutorial saya melihat orang-orang exportmengambil kelas mereka dan saya tidak dapat mengkompilasi kode saya jika saya tidak menambahkan defaultkata kunci sebelum mengekspor.

Juga, saya tidak dapat menemukan jejak kata kunci ekspor default di dokumentasi naskah resmi .

export class MyClass {

  collection = [1,2,3];

}

Tidak dikompilasi. Tapi:

export default class MyClass {

  collection = [1,2,3];

}

Apakah.

Kesalahannya adalah: error TS1192: Module '"src/app/MyClass"' has no default export.

fos.alex
sumber
Ini mungkin membantu: stackoverflow.com/q/32236163/218196
Felix Kling
3
Beberapa bacaan ringan pada topik. Mungkin membantu jika Anda menunjukkan bagaimana Anda mengimpor kelas ini, saya percaya di situlah kesalahan terjadi (Anda mungkin perlu mengubah sintaks impor untuk memperbaiki skenario kesalahan).
Sunil D.
5
"export" dan "export default" sama sekali bukan TypeScript - itu ES6.
Sensei James

Jawaban:

460

Ekspor Default ( export default)

// MyClass.ts -- using default export
export default class MyClass { /* ... */ }

Perbedaan utama adalah bahwa Anda hanya dapat memiliki satu ekspor default per file dan Anda mengimpornya seperti ini:

import MyClass from "./MyClass";

Anda bisa memberikannya nama apa saja yang Anda suka. Misalnya ini berfungsi dengan baik:

import MyClassAlias from "./MyClass";

Ekspor Bernama ( export)

// MyClass.ts -- using named exports
export class MyClass { /* ... */ }
export class MyOtherClass { /* ... */ }

Saat Anda menggunakan ekspor bernama, Anda dapat memiliki beberapa ekspor per file dan Anda perlu mengimpor ekspor yang dikelilingi dalam kurung:

import { MyClass } from "./MyClass";

Catatan: Menambahkan kawat gigi akan memperbaiki kesalahan yang Anda gambarkan dalam pertanyaan Anda dan nama yang ditentukan dalam kawat gigi harus cocok dengan nama ekspor.

Atau katakan file Anda mengekspor beberapa kelas, maka Anda dapat mengimpor keduanya seperti:

import { MyClass, MyOtherClass } from "./MyClass";
// use MyClass and MyOtherClass

Atau Anda dapat memberikan salah satu dari mereka nama yang berbeda di file ini:

import { MyClass, MyOtherClass as MyOtherClassAlias } from "./MyClass";
// use MyClass and MyOtherClassAlias

Atau Anda dapat mengimpor semua yang diekspor dengan menggunakan * as:

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

Yang mana untuk digunakan?

Dalam ES6, ekspor default ringkas karena use case mereka lebih umum ; Namun, ketika saya bekerja pada kode internal ke proyek di TypeScript, saya lebih suka menggunakan ekspor bernama daripada ekspor default hampir sepanjang waktu karena itu bekerja sangat baik dengan kode refactoring. Sebagai contoh, jika Anda secara default mengekspor kelas dan mengganti nama kelas itu, itu hanya akan mengubah nama kelas dalam file itu dan bukan salah satu dari referensi lain di file lain. Dengan ekspor bernama itu akan mengubah nama kelas dan semua referensi ke kelas itu di semua file lainnya.

Itu juga memainkan sangat baik dengan file barel (file yang menggunakan ekspor namespace export *- untuk mengekspor file lain) Contoh dari ini ditunjukkan di bagian "contoh" dari jawaban ini .

Perhatikan bahwa pendapat saya tentang menggunakan ekspor bernama bahkan ketika hanya ada satu ekspor bertentangan dengan TypeScript Handbook - lihat bagian "Bendera Merah". Saya percaya rekomendasi ini hanya berlaku ketika Anda membuat API untuk digunakan orang lain dan kode tidak internal untuk proyek Anda. Saat saya merancang API untuk digunakan orang, saya akan menggunakan ekspor default sehingga orang dapat melakukannya import myLibraryDefaultExport from "my-library-name";. Jika Anda tidak setuju dengan saya tentang melakukan ini, saya akan senang mendengar alasan Anda.

Yang mengatakan, cari apa yang Anda inginkan! Anda bisa menggunakan satu, yang lain, atau keduanya sekaligus.

Poin Tambahan

Ekspor default sebenarnya adalah ekspor bernama dengan nama default, jadi jika file memiliki ekspor default maka Anda juga dapat mengimpor dengan melakukan:

import { default as MyClass } from "./MyClass";

Dan perhatikan cara-cara lain untuk mengimpor ini: 

import MyDefaultExportedClass, { Class1, Class2 } from "./SomeFile";
import MyDefaultExportedClass, * as Classes from "./SomeFile";
import "./SomeFile"; // runs SomeFile.js without importing any exports
David Sherret
sumber
3
apa yang terjadi import myAlias = require("./PathToFile")dan yang ada export = IInterfaceOrClassdalam file? Apakah itu kuno sekarang?
BenCr
@ BenCr ya, ini adalah cara ES6 baru
David Sherret
Mengapa Anda tidak memberikan contoh 'Ekspor Bernama'?
Stato Machino
aws-sdk / clients / sns tidak memiliki ekspor default dan ketika mengakses sns menggunakan impor sns dari '/ sns' saya tidak mendapatkan ekspor tetapi impor myAlias ​​= memerlukan ("./ PathToFile") berfungsi. dapatkah saya melakukan sesuatu untuk mengubahnya mengimpor sns dari '/ sns' tanpa membuat perubahan sumber?
Jeson Dias
Jika Anda tidak secara eksplisit memasukkan kata kunci defaultapakah masih akan ada ekspor default yang tersedia di file itu? jika demikian apa aturannya.
Simon_Weaver
10

Saya mencoba untuk memecahkan masalah yang sama, tetapi menemukan saran yang menarik oleh Basarat Ali Syed , dari ketenaran TypeScript Deep Dive , bahwa kita harus menghindari export defaultdeklarasi generik untuk suatu kelas, dan sebagai gantinya menambahkan exporttag ke deklarasi kelas. Kelas yang diimpor seharusnya terdaftar dalam importperintah modul.

Itu adalah: bukannya

class Foo {
    // ...
}
export default Foo;

dan sederhana import Foo from './foo';dalam modul yang akan diimpor, kita harus menggunakannya

export class Foo {
    // ...
}

dan import {Foo} from './foo'di importir.

Alasannya adalah kesulitan dalam refactoring kelas, dan pekerjaan tambahan untuk ekspor. Posting asli oleh Basarat dalam export defaultdapat menyebabkan masalah

Hilton Fernandes
sumber
0

Inilah contoh dengan mengekspor objek sederhana.

var MyScreen = {

    /* ... */

    width : function (percent){

        return window.innerWidth / 100 * percent

    }

    height : function (percent){

        return window.innerHeight / 100 * percent

    }


};

export default MyScreen

Di file utama (Gunakan saat Anda tidak ingin dan tidak perlu membuat instance baru) dan itu bukan global, Anda hanya akan mengimpor ini saat dibutuhkan:

import MyScreen from "./module/screen";
console.log( MyScreen.width(100) );
Nikola Lukic
sumber