はじめに
どっちの時に { } をつける?つけない?
default export / import
named export / import
defalut export / import には気をつけろ!
default exportは、モジュール内で 1つだけ エクスポートすることができる。
import時に 独自の名前 を作成する必要がある。
異なる名前を使用することができてしまうという罠
・誤用される余地がある。
・exportする関数名や変数名が変わって、名前の不一致につながりやすい。
(呼び出し側ではエラーが出ない)
import時、関数名や変数名を変えると、コードの保守性や可読性を損なう。
const hogeFn = () => {
return <h1>サンプル</h1>;
}
export default hogeFn;
import hogeFn from './Hoge' // 通常、名前を変える事なく直接使用できる。
import fugaFn from './Hoge' // hogeFnをfugaFn(export時の別名)としてもエラーにならない。
import時、変数名が変わっても参照する値は同じ(直感的にわからない)
const a = 100;
export default a; // モジュール内から1つだけexportできる
import b from "./Hoge"; // 'a'→'b'(export時の別名)としても、'b'は'a'の値を参照
console.log(b); // 100
named export / import に対して { } が使える
named export / importはモジュールごとに複数持てる。
export時とimport時の名前が一致している必要がある。
const testVar = 'test'
const testFunc = () => console.log('Function')
// 作成した変数や関数を{ }を使用し複数exportできる。
export { testVar, testFunc }
// 変数や関数の宣言と同時にエクスポートすることも可能
// export const testVar = 'test';
// export const testFunc = () => console.log('Function');
// var, let, const, function, class がエクスポート可能
// 同じファイルで両方でも、片方だけでも使用する事が可能。export時点と変数名、関数名は同じ。
import { testVar, testFunc } from './Test'
// named export/importの場合は、単体でも{ }を使う。
import { testVar } from './Test'
console.log(testVar); // 'test'
testFunc(); // 'Function'とコンソール出力される
////////////////// as 別名 でimportする事もできる。 //////////////////
import { testVar as myVar, testFunc as myFunc } from "./Test"
console.log(myVar); // 'test'
myFunc(); // 'Function'とコンソール出力される
結果
default export | named export | |
---|---|---|
exportできる数 | 1つ | 複数でも可 |
import時の名前 | 任意 | export時と同じ |
{ } |
![]() |
![]() |
おまけ 1 :集約する時、ワイルドカード * の使い方に注意
import * from "mod"; → 使えない
import * as 任意の別名 from "mod";
import集約:複数の名前付きエクスポートを1つのオブジェクトとしてまとめて利用するために使用される。これにより、同じ名前の変数や関数が他のインポートと衝突するリスクを減らすことができる。また、異なるモジュールから同じ名前のエクスポートが行われている場合、別名を付けてそれぞれを区別する必要がある。
// exportするTest.jsファイル
export const a = 100;
export const b = 200;
// importするファイル
import * as testModule from "./Test";
console.log(testModule.a); // 100
console.log(testModule.b); // 200
import * as testModule from "./Test"; は、Test.js でエクスポートされたすべての名前付きエクスポート(a と b)を testModule という名前のオブジェクトに集約。これにより、testModule.a および testModule.b を使ってそれぞれの値にアクセスすることができる。
export * from "mod";
mod モジュールのすべての名前付きエクスポートを現在のモジュールから再エクスポートするための文。使い所として注意するべきは、同じ名前でエクスポートしない事。
// -- mod1.js --
export const a = 1; // 名前付きエクスポート
// -- mod2.js --
export const a = 3; // 名前付きエクスポート
// -- barrel.js --
export * from "./mod1.js";
export * from "./mod2.js";
// -- main.js --
import * as ns from "./barrel.js"; //集約import
console.log(ns.a); // undefined
//共通の名前aで再エクスポートする2つのワイルドカードのexport文があったため衝突し、undefined
おまけ2:セミコロンはつける?つけない?
関数宣言には、末尾のセミコロンは不要。
export function functionName() { /* … / }
export class ClassName { / … */ }
クラスや関数の前の export はそれを 関数式 にはしない。
エクスポートされているが、関数宣言です。
リストのエクスポートには、末尾にセミコロンはつける。
export { name1, /* …, */ nameN };
function sayHello(user) {
console.log(`Hello, ${user}!`);
}
function sayBye(user) {
console.log(`Bye, ${user}!`);
}
export {sayHello, sayBye}; // エクスポートされた変数のリストには末尾にセミコロンをつける
おまけ3:実際のエラーメッセージ
export 'Item' (imported as 'Item') was not found in './Item' (possible exports: default)
default exportに対して、import { } from XX の形式でimportしたために、不一致となりエラーが発生
// Item.js
const Item = { name: 'Hoge' };
export default Item;
import Item from './Item';
// import { Item } from './Item'; にするとエラーが発生するので注意!!
参考
export - JavaScript | MDN
import - JavaScript | MDN
エクスポートとインポート
named exportとdefault exportの違いを理解する
JavaScript: Default Exportは、値を「default」という名前でNamed Exportしている