ES6の `export const`と` export default`の比較


204

私はこれらの2つの間に大きな違いがあるかどうかを判断しようとしexport defaultています。

import myItem from 'myItem';

そしてexport const私ができることを使用して:

import { myItem } from 'myItem';

これ以外の違いやユースケースはあるのでしょうか。


1
を使用constすると、識別子が読み取り専用になります。したがって、プリミティブ値の場合、それは不変であると考えることができます。値自体は不変ではないので、オブジェクトや配列などを変更することができることに注意してください。再割り当てするだけではありません。
spmurrayzzz 2015年

4
@spmurrayzzz:FWIW、インポートバインディングも同様に不変constです。
Felix Kling

説明をありがとう@FelixKling、それを知らなかった
spmurrayzzz

@FelixKling:少なくとも、外から。それらは一定ではないかもしれませんが、エクスポートは変更できます。
Bergi、2015年

@Bergi:そう、私がインポートバインディングと言ったのはそのためです;)
Felix Kling

回答:


327

これは、名前付きエクスポートとデフォルトエクスポートです。export constconst宣言をエクスポートする名前付きエクスポートです。

ここで重要なのは、const宣言を宣言するために使用されるexportキーワードconstです。exportクラスや関数の宣言など、他の宣言にも適用できます。

デフォルトのエクスポート(export default

ファイルごとに1つのデフォルトのエクスポートを設定できます。インポートするときは、次のように名前を指定してインポートする必要があります。

import MyDefaultExport from "./MyFileWithADefaultExport";

これには任意の名前を付けることができます。

名前付きエクスポート(export

名前付きエクスポートでは、ファイルごとに複数の名前付きエクスポートを作成できます。次に、中かっこで囲む必要のある特定のエクスポートをインポートします。

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

または、同じステートメントで名前付きインポートとともにデフォルトを使用することもできます。

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

名前空間のインポート

オブジェクトのファイルからすべてをインポートすることもできます。

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

ノート

  • シンタックスでは、デフォルトのエクスポートを使用する方が一般的であるため、少しだけ簡潔にしています(ここの説明を参照してください)。
  • デフォルトのエクスポートは実際には名前付きの名前付きエクスポートであるdefaultため、名前付きインポートでインポートできます。

    import { default as MyDefaultExport } from "./MyFileWithADefaultExport";

24

export defaultエクスポートされた「もの」をインポートするとき、エクスポートされたものを何でもインポートできるようにするimportとき、それが「デフォルト」としてマークされているため、エクスポートされたときの名前に関係なく、それ自体で名前を選択することにより、構文に影響します。

私が気に入っている(そして使用している)便利なユースケースは、明示的に名前を付ける必要なし匿名関数をエクスポートできることです。その関数をインポートする場合にのみ、名前を付ける必要があります。


例:

2つの関数をエクスポートします。1つは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;
}

上記の関数をインポートします。default1つの名前を構成する:

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

とき{}構文は関数(または変数)をインポートするために使用され、それは何がインポートされることを意味してすでにエクスポートしたときに1にしてインポートしなければならないので、名前の正確な同じ名前、または他の輸入は動作しません。


誤った例:

  1. デフォルトの関数を最初にインポートする必要があります

    import {divide}, square from './module_1.js
  2. divide_1でエクスポートされなかったmodule_1.jsため、何もインポートされません

    import {divide_1} from './module_1.js
  3. square名前付きエクスポートのみを明示的に検索するようエンジンに指示するmodule_1.jsため、ではエクスポートされませんでした。{}

    import {square} from './module_1.js

1つのものをエクスポートするという意味ではありません。同じモジュールに複数の名前付きと1つのデフォルトを含めることができます。デフォルトとは、まさにそれを意味します-インポート時に、つまりのimport something from代わりに名前を指定しない場合、それはデフォルトのエクスポートですimport { somethingNamed } from
Andris

私もここで新しい英語の単語を学びました:そのための「誤った」+1
ユヴァル・レヴィ

12

マイナーな注意:デフォルトのエクスポートからインポートする場合、命名は完全に独立していることを考慮してください。これは実際にはリファクタリングに影響を与えます。

次のFooようなクラスに対応するインポートがあるとします。

export default class Foo { }

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

FooクラスをリファクタリングしBar、ファイルの名前を変更しても、ほとんどのIDEはインポートに影響しません。だからあなたはこれで終わるでしょう:

export default class Bar { }

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

特にTypescriptでは、名前付きエクスポートと信頼性の高いリファクタリングに本当に感謝しています。違いは、defaultキーワードと中括弧がないことだけです。また、この時点でタイプチェックが行われているため、インポート時にタイプミスを防ぐことができます。

export class Foo { }

//'Foo' needs to be the class name. The import will be refactored
//in case of a rename!
import { Foo } from './Foo'

2
" 'Foo'はクラス名である必要があります。 "-いいえ!デフォルトのエクスポートと同じように簡単に実行import { Foo as Anything } from …できimport Anything from …ます。
Bergi

あなたがいることができて、名前を変更すると、asそのソースコメントに本当にポイントではありません。反対票をいただきありがとうございます; p
Philipp Sumi

1
私は反対投票しませんでしたが、その議論が説得力があるかどうかはわかりません。単一のモジュールをリファクタリングするときにIDEですべてのインポートの名前を変更する必要があるかどうかはわかりません。これがまさにモジュール化に関するものです。 …
Bergi、

ここでは開発者UXのために名前付きエクスポートを使用することに同意します。私は頻繁にリファクタリングしますが、通常、ファイルごとに1つのクラス(私の場合:React Component)を持っているので、切断を作成しないように、名前が変更されたコンポーネントに従ってインポートを絶対に実行します。もちろん、これは個々の開発者によっては意味のある場合とそうでない場合があります。
Philipp Sumi

同じことを言う記事を見つけまし。多分妥当な位置かもしれません:export defaultプロジェクトのメインオブジェクトを、特にnpmパッケージからエクスポートするために使用する必要があります(それはを置き換えますmodule.exports =)。ただし、プロジェクトの内部では、名前付きエクスポートのみを使用することをお勧めします。
パレオ、

7

ドキュメントから:

名前付きエクスポートは、いくつかの値をエクスポートするのに役立ちます。インポート中、同じ名前を使用して対応する値を参照できます。

デフォルトのエクスポートに関しては、モジュールごとに1つのデフォルトのエクスポートのみがあります。デフォルトのエクスポートには、関数、クラス、オブジェクトなどがあります。この値は最も簡単にインポートできるため、「メイン」のエクスポート値と見なされます。


0

デフォルトを設定すると、そのデフォルトのエクスポートが呼び出されます。デフォルトのエクスポートはファイルごとに1つだけで、任意の名前で別のファイルにインポートできます。デフォルト、つまり名前付きエクスポートを指定しない場合は、中括弧を含む同じ名前の別のファイルにインポートする必要があります。


0

ブラウザがes6を使用しないという問題がありました。

私はそれを修正しました:

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

タイプモジュールは、ブラウザにES6を使用するように指示します。

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

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

その後、動作するはずです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.