【JavaScriptの超基本】ファイルのインポートやエクスポートについて簡単に解説

#概要

この記事では、JavaScriptのファイルのインポートやエクスポートについて、超基本的な知識をメモ的にまとめています。
自分用の備忘録なのであしからず。

今回使うコードの詳細はこの記事では、説明しません。
コードの詳細は以下の記事で解説しているので、興味があればご覧ください。

[【JavaScriptの超基本】クラスの定義やメソッド・継承について簡単に解説](https://qiita.com/ta1fukumoto/items/d0c2e54e26e7ef76d6cf)




#目次

- [ファイルの分割](#ファイルの分割)
- [エクスポート](#エクスポート)
    - [名前付きエクスポート](#名前付きエクスポート)
    - [デフォルトエクスポート](#デフォルトエクスポート)
    - [名前付きエクスポートとデフォルトエクスポートの違い](#名前付きエクスポートとデフォルトエクスポートの違い)
- [インポート](#インポート)
    - [別名インポート](#別名インポート)
    - [デフォルトエクスポートされた値のインポート](#デフォルトエクスポートされた値のインポート)
- [相対パス](#相対パス)
- [まとめ](#まとめ)




#ファイルの分割

コードが増えてくると1つのファイルで管理するのが大変になるため、複数のファイルに分けて管理します。
ファイルを分けて管理することでバグを見つけやすくなるというメリットもあります。

今回は、[こちら](https://qiita.com/ta1fukumoto/items/d0c2e54e26e7ef76d6cf)の記事で作成したコードを分割して管理するようにしていきます。

まず、それぞれのクラスを定義するファイルとメインのプログラムを実行するファイルに分けます。

```script.js
const forward = new Forward('Messi', 10);
forward.introduce();
console.log(forward);
```

```barcelona.js
class Barcelona {
    constructor(name, uniformNumber) {
        this.name = name;
        this.uniformNumber = uniformNumber;
    }
    introduce() {
        console.log(`FC Barcelonaの背番号${this.uniformNumber}は${this.name}です`);
    }
}
```

```forward.js
class Forward extends Barcelona {
    constructor(name, uniformNumber) {
        super(name, uniformNumber);
        this.position = 'FW'
    }
    introduce() {
        console.log(`FC Barcelonaの背番号${this.uniformNumber}は${this.name}です`);
        this.introducePosition();
    }
    introducePosition() {
        console.log(`ポジションは${this.position}です`);
    }
}
```

このような感じでファイルを分割しました。
ファイルを分割しただけだとエラーが起きてしまうので、それぞれのファイルを関連づけるためにファイルのエクスポートとインポートをしていきます。

> *※注意*
ファイルをインポートしたりエクスポートしたりするには、ファイルをモジュール化する必要があります。今回詳しくは解説しませんが、JavaScriptを書いているファイルがあるフォルダ内に次のファイルを追加してくだい。

```package.json
{
    "type": "module"
}
```




#エクスポート

クラスや関数などを他のファイルで使うためには、まずそれらを定義した後に、そのファイルから**エクスポート（出力）**しないといけません。

エクスポートは、大きく「**名前付き**」と「**デフォルト**」の2種類に分類されます。

それぞれ見ていきましょう！




##名前付きエクスポート

ファイル内で定義してあるクラスや関数、定数などは`export { 〇〇 } `とすることでエクスポートすることができます。これを「**名前付きエクスポート**」と言います。

名前付きエクスポートでは、複数の値のエクスポートが可能です。
その場合、`export { 〇〇, ×× } `のように`,`で区切って書きましょう。

```example.js
//定義
const 定数名 = ... ;
let 変数名 =  ... ;
function 関数名() { ... };
class クラス名 { ... };

//事前に定義された機能をエクスポート
export { 定数名 };

//複数の機能をエクスポート
export { 変数名, 関数名, クラス名 };
```

また、それぞれの機能は定義する際に個別に定義することもできます。

```example.js
//定義と同時にエクスポート
export const 定数名 = ... ;
export function 関数名() { ... }
```




##デフォルトエクスポート

もう一つのエクスポートの方法が「**デフォルトエクスポート**」です。
クラスや関数を定義した後に`export default 〇〇`と書くことで、他のファイルでも使えるようにエクスポートできます。

```example.js
//事前に定義された定数をデフォルトエクスポート
export default 定数名;

//事前に定義された関数をデフォルトエクスポート
export default 関数名;
```

デフォルトエクスポートは、名前付きエクスポートと同様に定義と同時にエクスポートすることも可能です。

```example.js
//定義と同時にエクスポート
export default const 定数名 = ... ;
```

では、Barcelonaクラスをデフォルトエクスポートしてみます。

```barcelona.js
//クラスを定義
class Barcelona {
    :
    :
}

//Barcelonaクラスをエクスポート
export default Barcelona;
```

エクスポートすることでBarcelonaクラスを他のファイルに渡す準備が整いました。





##名前付きエクスポートとデフォルトエクスポートの違い

名前付きエクスポートは、**エクスポートできるファイルの数に制限はありません**が、デフォルトエクスポートは、**1ファイルにつき1つの値のみ**使えます。

これはデフォルトエクスポートの性質に関連しています。
デフォルトエスクポートされたファイルをインポートすると`export default 〇〇`と書いた`〇〇`の値が**自動的にインポートされる**という性質を持っています。

この性質から、**エクスポート時の値とインポート時の値は、名前が異なっていても問題ありません**。




#インポート

エクスポートされた値をインポートするには`import { 〇〇 } from “ファイルへのパス”`と書きます。

複数の値をインポートする際は、エクスポート時と同様に`{ }`の中の値を`,`で区切って書きます。

```example.js
//値のインポート
import {定数名} from "ファイルへのパス";

//複数の値のインポート
import {変数名, 関数名, クラス名} from "ファイルへのパス";
```

名前付きでエクスポートされた値は、このようにしてインポートします。

ファイル名は、基本的に相対パスで書きます。相対パスについては後ほど解説します。




##別名インポート

エクスポートした値を別名（エイリアス）でインポートすることもできます。

その場合には、以下のように書きます。

```example.js
//別名インポート
import { 〇〇 as エイリアス } form “ファイルへのパス”
```

別名でインポートした値を使いたい場合は、`エイリアス`を用いて使うことができます。

また、`*`を用いると任意のファイルでエクスポートした全ての値をインポートすることができます。
その場合は、`as モジュール名`としてインポートします。

構文は以下の通りです。

```example.js
import { * as モジュール名 } form “ファイルへのパス”
```

インポートした値を使いたい場合は、`モジュール名.〇〇`のように書くことでインポートしたファイルでも使うことができます。




##デフォルトエクスポートされた値のインポート

デフォルトエクスポートされた値を読み込む際は、`import 〇〇 from “./ファイル名”`とします。名前付きインポートとは異なり`{ }`が必要ありません。

先ほど説明したように、デフォルトエクスポートされた値の場合は、エクスポート時の名前とインポート時の名前は異なっていても問題ありません。（例えば、エクスポートしたファイルでは〇〇 という名前の値だが、インポートするファイルでは△△という名前にする）

先ほど分割したファイルに、エクスポートとインポートのコードを追加します。Barcelonaクラスはデフォルトエクスポート、Forwardクラスは名前付きエクスポートし、それぞれインポートします。

BarcelonaクラスはBarcaという名前でインポートします。その際、Barcelonaというクラス名はインポートしたファイルでは使えないので、クラス名をBarcaに書き換えます。

```script.js
//Forwardクラスをインポート
import {Forward} from "./forward.js";

const forward = new Forward('Messi', 10);
forward.introduce();
console.log(forward);
```

```barcelona.js
class Barcelona {
    constructor(name, uniformNumber) {
        this.name = name;
        this.uniformNumber = uniformNumber;
    }
    introduce() {
        console.log(`FC Barcelonaの背番号${this.uniformNumber}は${this.name}です`);
    }
}

//Barcelonaクラスをデフォルトエクスポート
export default Barcelona;
```

```forward.js
//BarcelonaクラスをBarcaという名前でインポート
import Barca from "./barcelona.js";

//クラス名をBarcaに書き換える
class Forward extends Barca {
    constructor(name, uniformNumber) {
        super(name, uniformNumber);
        this.position = 'FW'
    }
    introduce() {
        console.log(`FC Barcelonaの背番号${this.uniformNumber}は${this.name}です`);
        this.introducePosition();
    }
    introducePosition() {
        console.log(`ポジションは${this.position}です`);
    }
}

//Forwardクラスを名前付きエクスポート
export {Forward};
```

この状態で「script.js」ファイルを実行すると正常に処理が実行されます。




#相対パス

ファイル名の記述には、通常「**相対パス**」を用います。
相対パスでは、記述されたファイルから見た位置関係でファイル名を示します。

これまで書いてきたファイル名の前についている`./`は相対パスが書かれているファイルと同じディレクトリを意味します。

以下のようなフォルダ階層になっているとします。

```
test
├── script.js
└── class
    ├── barcelona.js
    └── forward.js
```

`script.js`で`barcelona.js`を読み込みたいときは`./class/barcelona.js`と書きます。

一つ上のディレクトリに移動するには`../`と書くことで指定することができます。
`barcelona.js`で`script.js`を読み込みたいときは`../script.js`と書きます。




#まとめ

ファイルの分割は、実際にコードを書く際には非常に大事なのでエクスポートやインポートをしっかり理解しましょう。

最後まで読んでいただいてありがとうございます。では。