【初心者】エクスポート・インポート記述メモ（ CommonJS Modules構文 ）【備忘録】

# はじめに

投稿時点で、筆者は知識ゼロの状態から勉強を初めて2ヶ月程度の実力です。
そのため、理解不足や説明不足、誤った内容や呼び方をしている可能性があります。
万が一参考にする場合は上記の点を考慮した上でご一読ください。
説明文の内容はChatGPT先生からの引用も多いです。

# 本題
「CommonJS Modules」
以下、ChatGPT先生より引用。
>ECMAScript ModulesとCommonJS Modulesは、JavaScriptのモジュールシステムの2つの主要な形式です。これらの形式は、異なるシステムで使用されるため、それぞれの違いを理解することが重要です。
CommonJS Modulesは、Node.jsで広く使用される形式です。この形式は、require関数を使用してモジュールを読み込み、module.exportsまたはexportsオブジェクトを使用してモジュールをエクスポートします。また、動的な構造を持ち、モジュールの読み込みは同期的に行われます。
簡単に言うと、CommonJS Modulesは、require関数を使用して、動的な構造を持ち、同期的にモジュールを読み込むことができます。

ECMAScriptのエクスポート・インポート記述については下記にまとめました。
[【初心者】エクスポート・インポート記述メモ（ ECMAScript Modules [ ESM ] 構文 ）【備忘録】](https://qiita.com/miyaayim_study/items/29a9090c94b2de9277d8)

ここでは関数、定数のエクスポート・インポートを例にしています。

## エクスポート

エクスポート（出力）する手段は下記の3パターンがある。
1. `module.exports = 値`
2. `module.exports.名前 = 値`
3. `exports.名前 = 値`

### module.exports

#### エクスポート例（1つの値のみを渡す場合）

##### ～ 通常の関数の場合 ～

###### 1.名前なし関数（関数式 [ 無名関数 / 関数リテラル ]）

```javascript
module.exports = function () { /*…*/ }; // 無名関数を直接エクスポート
```

```javascript
const Counter = function () { /*…*/ }; // 無名関数をCounterという定数名で定義
module.exports = Counter; // 定数Counterをエクスポート
```

###### 2.名前付き関数（関数宣言 [ function文 ] ）

```javascript
module.exports = function Counter() { /*…*/ }; // Counterという関数を定義し、それを直接エクスポート
```

```javascript
function Counter() { /*…*/ }; // 関数をCounterという関数名で定義
module.exports = Counter; // 関数Counterをエクスポート
```

```javascript
function myFunction() { /*…*/ }; // 関数をmyFunctionという関数名で定義
const Counter = myFunction; // 関数myFunctionをCounterという定数名で定義
module.exports = Counter; // 定数Counterをエクスポート
```

##### ～ アロー関数の場合 ～

アロー関数では、通常の関数定義とは異なり、名前付き関数を定義することはできません。
アロー関数では **`function`** 文を使用せずに名前付き関数を定義することはできません。

###### 名前なし関数（関数式 [ 無名関数 / 関数リテラル ]）

```javascript
module.exports = () => { /*…*/ }; // 無名のアロー関数を直接エクスポート
```

```javascript
const Counter = () => { /*…*/ }; // 無名のアロー関数をCounterという定数名で定義
module.exports = Counter; // 定数Counterをエクスポート
```

#### エクスポート例（復数の値のみを渡す場合）

まずはNG例から紹介します。

～ NG例 ～

```javascript
module.exports = function Counter() { /*…*/ }; // Counterという関数を定義し、それを直接エクスポート
module.exports = function Button() { /*…*/ }; // Buttonという関数を定義し、それを直接エクスポート
```

```javascript
module.exports = () => { /*…*/ }; // 無名のアロー関数を直接エクスポート
module.exports = () => { /*…*/ }; // 無名のアロー関数を直接エクスポート
```

```javascript
const Counter = () => { /*…*/ }; // 無名のアロー関数をCounterという定数名で定義
const Button = () => { /*…*/ }; // 無名のアロー関数をButtonという定数名で定義
module.exports = Counter; // 定数Counterをエクスポート
module.exports = Button; // 定数Buttonをエクスポート
```

上記のパターンは全てNGです。
理由は、2回目の`module.exports`が、1回目の`module.exports`を上書きしてしまうためです。
複数の値を渡したい場合は下記のようなやり方があります。



```javascript
const Counter = () => { /*…*/ }; // 無名のアロー関数をCounterという定数名で定義
const Button = () => { /*…*/ }; // 無名のアロー関数をButtonという定数名で定義
module.exports = { Counter, Button }; // 定数Counterと定数Buttonをエクスポート
```

```javascript
const Counter = () => { /*…*/ }; // 無名のアロー関数をCounterという定数名で定義
const Button = () => { /*…*/ }; // 無名のアロー関数をButtonという定数名で定義
module.exports = {
  Counter: Counter, // 定数CounterをCounterという名前でエクスポート
  Button: Button // 定数ButtonをButtonという名前でエクスポート
};
```

これは2つとも同じ役割となり、どちらも分割代入を利用してエクスポートしています。
1つめの記述は2つめの記述を省略したやり方です。
2つめをみると、エクスポートする際にどれが何かを識別できるように名前を付与しているのがわかります。
このように、復数の値をエクスポートする際には名前を付与する必要があります。
もし別名でエクスポートしたい場合は下記の例がわかりやすいです。

```javascript
const Counter = () => { /*…*/ }; // 無名のアロー関数をCounterという定数名で定義
const Button = () => { /*…*/ }; // 無名のアロー関数をButtonという定数名で定義
module.exports = {
  myCounter: Counter, // 定数CounterをmyCounterという名前でエクスポート
  myButton: Button // 定数ButtonをmyButtonという名前でエクスポート
};
```

実際は、複数のモジュールで同じ変数名を使用することが多いため、本来はプロパティ名と変数名を一致させるほうが一般的だそうです。（例：`Counter: Counter`）
ここで、復数の値をエクスポートするやり方を紹介しましたが、復数の値を渡す際のやり方は他にもあります。
そのやり方は、`module.exports`の後に`.名前`で名前を付与することです。
ですので、 `module.exports.名前 = 値`という記述になります。

```javascript
module.exports.myCounter = function Counter() { /*…*/ }; // Counterという関数を定義し、それをmyCounterという名前で直接エクスポート
module.exports.myButton = function Button() { /*…*/ }; // Buttonという関数を定義し、それをmyButtonという名前で直接エクスポート
```

```javascript
module.exports.myModule1 = () => { /*…*/ }; // 無名のアロー関数をmyModule1という名前で直接エクスポート
module.exports.myModule2 = () => { /*…*/ }; // 無名のアロー関数をmyModule2という名前で直接エクスポート
```

```javascript
const Counter = () => { /*…*/ }; // 無名のアロー関数をCounterという定数名で定義
const Button = () => { /*…*/ }; // 無名のアロー関数をButtonという定数名で定義
module.exports.myCounter = Counter; // 定数CounterをmyCounterという名前でエクスポート
module.exports.myButton = Button; // 定数ButtonをmyButtonという名前でエクスポート
```

ちなみに、下記2つは同じ役割になります。

```javascript
const Counter = () => { /*…*/ }; // 無名のアロー関数をCounterという定数名で定義
const Button = () => { /*…*/ }; // 無名のアロー関数をButtonという定数名で定義
module.exports.myCounter = Counter; // 定数CounterをmyCounterという名前でエクスポート
module.exports.myButton = Button; // 定数ButtonをmyButtonという名前でエクスポート
```

```javascript
const Counter = () => { /*…*/ }; // 無名のアロー関数をCounterという定数名で定義
const Button = () => { /*…*/ }; // 無名のアロー関数をButtonという定数名で定義
module.exports = {
  myCounter: Counter, // 定数CounterをmyCounterという名前でエクスポート
  myButton: Button // 定数ButtonをmyButtonという名前でエクスポート
};
```

### exports

`module.exports.名前 = 値`　の先頭の`mojule.`を消して、`exports.名前 = 値`　という記述でもエクスポートすることができます。
`module.exports`と`exports`　は本質的に役割が異なるとChatGPT先生は仰っていますが、よくわかりませんでした。
自分は、`exports`は`module.exports`の省略形、`module.exports` ＝ `exports`みたいに覚えています。
唯一異なるのは、`module.exports = 値`はOKだが、`exports = 値`はNGということぐらいでしょうか。
一応最後に、`module.exports`と`exports`を比較した例を作ったので、よければご覧ください。
以下には、ChatGPT先生に質問した回答メモを残しておきます。

>`exports`を使用する意味は、`module.exports`を簡略化することにあります。
つまり、`exports`は、`module.exports`オブジェクトへの参照を持つ特別なオブジェクトです。
これにより、`exports`を使用して、`module.exports`に直接プロパティを追加することができます。
しかし、`exports`オブジェクトに直接プロパティを割り当てた場合、`exports`オブジェクトが`module.exports`オブジェクトと異なるオブジェクトになってしまい、予期しないエラーが発生する可能性があることに注意する必要があります。
そのため、一般的には、`exports`を使用する代わりに、常に`module.exports`を使用することをお勧めします。
ただし、複数の関数やオブジェクトをエクスポートする場合、`exports`を使用してオブジェクトを構築することができます。


>`exports`オブジェクトは、`module.exports`オブジェクトへの参照を持つ特別なオブジェクトであるため、`exports`オブジェクトに直接プロパティを割り当てた場合、`module.exports`オブジェクトとは別のオブジェクトになってしまいます。
この場合、`exports`オブジェクトに割り当てたプロパティは`module.exports`オブジェクトには影響を与えず、`module.exports`オブジェクトは空のオブジェクトのままになります。

>`module.exports`は最初に空のオブジェクトとして作成されるため、`exports`オブジェクトに直接プロパティを割り当てた場合、`module.exports`オブジェクトには反映されません。
これは、`exports`オブジェクトが`module.exports`オブジェクトを参照しているものの、`exports`オブジェクトに直接割り当てたプロパティは`module.exports`オブジェクトには影響を与えないためです。
例えば、以下のように`module.exports`オブジェクトに直接プロパティを割り当てると、`module.exports`オブジェクトにプロパティが追加されます。

```javascript
module.exports.名前 = 値;
```

>しかし、`exports`オブジェクトに直接プロパティを割り当てた場合は、`module.exports`オブジェクトには反映されません。

```javascript
exports.名前 = 値;
```

>この場合、`exports`オブジェクトは`module.exports`オブジェクトを参照していますが、`module.exports`オブジェクト自体には何も割り当てられていないため、空のオブジェクトのままになります。
ですので、上記3つのパターンは下記のように置き換えることができます。

```javascript
exports.myCounter = function Counter() { /*…*/ }; // Counterという関数を定義し、それをmyCounterという名前で直接エクスポート
exports.myButton = function Button() { /*…*/ }; // Buttonという関数を定義し、それをmyButtonという名前で直接エクスポート
```

```javascript
exports.myModule1 = () => { /*…*/ }; // 無名のアロー関数をmyModule1という名前で直接エクスポート
exports.myModule2 = () => { /*…*/ }; // 無名のアロー関数をmyModule2という名前で直接エクスポート
```

```javascript
const Counter = () => { /*…*/ }; // 無名のアロー関数をCounterという定数名で定義
const Button = () => { /*…*/ }; // 無名のアロー関数をButtonという定数名で定義
exports.myCounter = Counter; // 定数CounterをmyCounterという名前でエクスポート
exports.myButton = Button; // 定数ButtonをmyButtonという名前でエクスポート
```




ではここからは、最初の`module.exports`の記述例を全て`exports`に置き換えてみました。（自分がわかりやすくするため）

#### ～ 通常の関数の場合 ～

##### 1.名前なし関数（関数式 [ 無名関数 / 関数リテラル ]）

```javascript
exports.Counter = function () { /*…*/ }; // 無名関数をCounterという名前で直接エクスポート
```

```javascript
const myConst = function () { /*…*/ }; // 無名関数をmyConstという定数名で定義
exports.Counter = myConst; // 定数myConstをCounterという名前でエクスポート
```

##### 2.名前付き関数（関数宣言 [ function文 ] ）

```javascript
exports.Counter = function myFunction() { /*…*/ }; // myFunctionという関数を定義し、それをCounterという名前で直接エクスポート
```

```javascript
function myFunction() { /*…*/ }; // 関数をmyFunctionという関数名で定義
exports.Counter = myFunction; // 関数myFunctionをCounterという名前でエクスポート
```

```javascript
function myFunction() { /*…*/ }; // 関数をmyFunctionという関数名で定義
const myConst = myFunction; // 関数myFunctionをmyConstという定数名で定義
exports.Counter = myConst; // 定数myConstをCounterという名前でエクスポート
```

#### ～ アロー関数の場合 ～

##### 名前なし関数（関数式 [ 無名関数 / 関数リテラル ]）

```javascript
exports.Counter = () => { /*…*/ }; // 無名のアロー関数をCounterという名前で直接エクスポート
```

```javascript
const myConst = () => { /*…*/ }; // 無名のアロー関数をmyConstという定数名で定義
exports.Counter = myConst; // 定数myConstをCounterという名前でエクスポート
```

まとめると、
復数の値を1つずつエクスポートする場合は

```javascript
module.exports.Counter = function Counter() { /*…*/ }; // Counterという関数を定義し、それをCounterという名前で直接エクスポート
module.exports.Button = function Button() { /*…*/ }; // Buttonという関数を定義し、それをButtonという名前で直接エクスポート
```

最後にまとめてエクスポートする場合は、

```javascript
const Counter = () => { /*…*/ }; // 無名のアロー関数をCounterという定数名で定義
const Button = () => { /*…*/ }; // 無名のアロー関数をButtonという定数名で定義
module.exports = { Counter, Button }; // 定数Counterと定数Buttonをエクスポート
```

というやり方が良いのではないでしょうか。

## インポート

インポート（読込）する手段は下記の2パターンがあります。
1. `const 名前 = require('./ファイル名');`
2. `const { 名前 } = require('./ファイル名');`

1.`const 名前 = require('./ファイル名');`の場合は、任意の名前を指名することができ、`module.exports = 値`としてエクスポートされた場合に使用できます。
2.`const { 名前 } = require('./ファイル名');`の場合は、名前をエクスポート時に指名した名前と一致させる必要があり、`module.exports.名前 = 値`、または、`exports.名前 = 値`としてエクスポートされた場合に使用できます。

下記に例をあげていきます。

1.エクスポートされた値をインポート

```javascript
const Counter = require('./modules'); // './modules'からエクスポートされた全ての値をインポートして、Counterという定数名で定義
```

2.復数エクスポートされた中から一部のみをインポートする場合

```javascript
const { Counter } = require('./modules'); // './modules'からCounterという名前でエクスポートされた値をインポートして、Counterという定数名で定義
```
エクスポート時と同様で、分割代入を利用しています。
そして、上記は省略した記述方法となり、実際は下記のようになっています。

```javascript
const {
  Counter : Counter, // Counterという名前のデータをCounterという名前でインポート
 } = require('./modules'); // './modules'からエクスポートされたデータをインポート
```

復数エクスポートする時と同じ記述と思えばわかりやすいかもしれません。

3.エクスポートされた値を1つにインポートする場合

```javascript
const Counter = () => { /*…*/ }; // 無名のアロー関数をCounterという定数名で定義
const Button = () => { /*…*/ }; // 無名のアロー関数をButtonという定数名で定義
module.exports = { Counter, Button }; // 定数Counterと定数Buttonをエクスポート
```

```javascript
const Counter = require('./modules'); // './modules'からエクスポートされた全ての値をインポートして、Counterという定数名で定義
```

このとき、Counterには下記の2つの値が入っています。

```javascript
const Counter = () => { /*…*/ }; // 無名のアロー関数をCounterという定数名で定義
const Button = () => { /*…*/ }; // 無名のアロー関数をButtonという定数名で定義
```

4.エクスポートされた中から一部のみをインポートする場合

```javascript
const Counter = () => { /*…*/ }; // 無名のアロー関数をCounterという定数名で定義
const Button = () => { /*…*/ }; // 無名のアロー関数をButtonという定数名で定義
module.exports = { Counter, Button }; // 定数Counterと定数Buttonをエクスポート
```

```javascript
const { Counter } = require('./modules'); // './modules'からCounterという名前でエクスポートされた値をインポートして、Counterという定数名で定義
```

このとき、Counterには下記の値のみが入っています。

```javascript
const Counter = () => { /*…*/ }; // 無名のアロー関数をCounterという定数名で定義
```

### ～ 複数の値をインポート ～

基本的にエクスポート時と同じ記述です。

```javascript
const { Counter, Button } = require('./modules'); // './modules'からエクスポートされた、Counter・Buttonというそれぞれの名前のデータを、同じ名前でインポート
```

上記は省略した記述方法で、実際は下記のようになっています。

```javascript
const {
  Counter : Counter, // Counterという名前のデータをCounterという名前でインポート
  Button : Button // Buttonという名前のデータをButtonという名前でインポート
 } = require('./modules'); // './modules'からエクスポートされたデータをインポート
```

もし名前を変更したい場合は下記のようになります。

```javascript
const {
  Counter : myCountre, // Counterという名前のデータをmyCounterという名前でインポート
  Button : myButton // Buttonという名前のデータをmyButtonという名前でインポート
 } = require('./modules'); // './modules'からエクスポートされたデータをインポート
```

## エクスポートとインポートを交えた例

1.シンプル（module.exports）

```javascript:components/modules.js
const Counter = () => { /*…*/ }; // 無名のアロー関数をCounterという定数名で定義
module.exports = Counter; // 定数Counterをエクスポート
```

```components/index.js
const myCounter = require('./modules'); // './modules'からエクスポートされた全ての値をインポートして、myCounterという定数名で定義
```

2.復数エクスポート（module.exports）

```javascript:components/modules.js
const Counter = () => { /*…*/ }; // 無名のアロー関数をCounterという定数名で定義
const Button = () => { /*…*/ }; // 無名のアロー関数をButtonという定数名で定義
module.exports = { Counter, Button }; // 定数Counterと定数Buttonをエクスポート
```

```components/index.js
const myModules = require('./modules'); // './modules'からエクスポートされた全ての値をインポートして、myModulesという定数名で定義
```

3.シンプル（exports）

```javascript:components/modules.js
const myConst = () => { /*…*/ }; // 無名のアロー関数をmyConstという定数名で定義
exports.Counter = myConst; // 定数myConstをCounterという名前でエクスポート
```

```components/index.js
const { Counter } = require('./modules'); // './modules'からCounterという名前でエクスポートされた値をインポートして、Counterという定数名で定義
```

4.復数エクスポート（exports）

```javascript:components/modules.js
const Counter = () => { /*…*/ }; // 無名のアロー関数をCounterという定数名で定義
const Button = () => { /*…*/ }; // 無名のアロー関数をButtonという定数名で定義
exports.Modules = { Counter, Button }; // 定数Counterと定数ButtonをModulesという名前でエクスポート
```

```components/index.js
const { Modules } = require('./modules'); // './modules'からModulesという名前でエクスポートされた値をインポートして、Modulesという定数名で定義
```

5.復数エクスポート、復数インポート（exports）

```javascript:components/modules.js
const Counter = () => { /*…*/ }; // 無名のアロー関数をCounterという定数名で定義
const Button = () => { /*…*/ }; // 無名のアロー関数をButtonという定数名で定義
exports.myCounter = Counter; // 定数CounterをmyCounterという名前でエクスポート
exports.myButton = Button; // 定数ButtonをmyButtonという名前でエクスポート
```

```components/index.js
const { myCounter, myButton } = require('./modules'); // './modules'からエクスポートされた、myCounter・myButtonというそれぞれの名前のデータを、同じ名前でインポート
```

NG例

```javascript:components/modules.js
const myConst = () => { /*…*/ }; // 無名のアロー関数をmyConstという定数名で定義
exports.Counter = myConst; // 定数myConstをCounterという名前でエクスポート
```

```components/index.js
const myCounter = require('./modules'); // './modules'からエクスポートされた全ての値をインポートして、myCounterという定数名で定義
```

`exports.Counter`という形式でエクスポートされた値をインポートする場合は、エクスポート時と同じ名前を指定して取り出す必要があります。
ですので正しく修正すると下記になります。

```components/index.js
const { Counter } = require('./modules'); // './modules'からCounterという名前でエクスポートされた値をインポートして、Counterという定数名で定義
```

復数エクスポートの例で例えるとわかりやすいかもしれません。

NG例2

```javascript:components/modules.js
const myConst1 = () => { /*…*/ }; // 無名のアロー関数をmyConst1という定数名で定義
const myConst2 = () => { /*…*/ }; // 無名のアロー関数をmyConst1という定数名で定義
exports.Counter1 = myConst1; // 定数myConst1をCounter1という名前でエクスポート
exports.Counter2 = myConst2; // 定数myConst2をCounter2という名前でエクスポート
```

```components/index.js
const myCounter = require('./modules'); // './modules'からエクスポートされた全ての値をインポートして、myCounterという定数名で定義
```

復数にすると、なぜ指定して取り出す必要があるのかわかりやすくなったと思います。これでは、`myCounter`に何を当てればいいのか判断できませんね。
`exports`では、`./modules`内の値の全てではなく一部分にフォーカスを当てているというイメージです。

### ～ 応用 ～

`module.exports`と`exports`は同時に使用可能です。

```javascript:components/modules.js
module.exports.Counter = () => { /*…*/ }; // 無名のアロー関数をCounterという名前で直接エクスポート
exports.Button = () => { /*…*/ }; // 無名のアロー関数をButtonという名前で直接エクスポート
```

```components/index.js
const { Counter, Button } = require('./modules'); // './modules'からエクスポートされた、Counter・Buttonというそれぞれの名前のデータを、同じ名前でインポート
```



わかりやすくするために、`console.log`を使用した例を上げていきます。
例1

```javascript:components/modules.js
module.exports.Counter = () => {
  return 'counter text';
};

exports.Button = () => {
  return 'button text';
};
```

```components/index.js
const myModule = require('./modules');
console.log(myModule.Counter()); // 出力結果：counter text
console.log(myModule.Button()); // 出力結果：button text
```

もしインポートの仕方を変えた場合はこのような出力結果となります。

```components/index.js
const { Counter } = require('./modules');
console.log(Counter()); // 出力結果：counter text
console.log(Button()); // 出力結果：エラー
```

例2

```javascript:components/modules.js
module.exports = () => {
  return 'counter text';
};

exports.Button = () => {
  return 'button text';
};
```

```components/index.js
const myModule = require('./modules');
console.log(myModule()); // 出力結果：counter text
console.log(myModule.Button()); // 出力結果：button text
```

間違えそうな例

```javascript:components/modules.js
module.exports.Counter = () => {
  return 'counter text';
};

exports.Button = () => {
  return 'button text';
};
```

```components/index.js
const Counter = require('./modules');
console.log(Counter()); // 出力結果：エラー
console.log(Button()); // 出力結果：エラー

// 正しくは下記

console.log(Counter.Counter()); // 出力結果：counter text
console.log(Counter.Button()); // 出力結果：button text
```

### ～ module.exports と exports の違いを知る ～

こうやったまとめると、全く違いがないようにみえます…。
実機で試さずに、ChatGPT先生に出力に聞きながら書いたので、間違っていたらすみません。

例1
```javascript:components/modules.js
module.exports = () => {
  return 'counter text';
};
```

```components/index.js
// パターン1
const Counter = require('./modules');
console.log(Counter()); // 出力結果：counter text

// パターン2
const { Counter } = require('./modules');
console.log(Counter()); // 出力結果：エラー
```

例2
```javascript:components/modules.js
exports = () => {
  return 'counter text';
};
```

```components/index.js
// パターン1
const Counter = require('./modules');
console.log(Counter()); // 出力結果：エラー

// パターン2
const { Counter } = require('./modules');
console.log(Counter()); // 出力結果：エラー
```


例3
```javascript:components/modules.js
module.exports.Counter = () => {
  return 'counter text';
};
```

```components/index.js
// パターン1
const Counter = require('./modules');
console.log(Counter()); // 出力結果：{ Counter: [Function: Counter] }

// パターン2
const Counter = require('./modules');
console.log(Counter.Counter()); // 出力結果：counter text

// パターン3
const { Counter } = require('./modules');
console.log(Counter()); // 出力結果：counter text
```

例4
```javascript:components/modules.js
exports.Counter = () => {
  return 'counter text';
};
```

```components/index.js
// パターン1
const Counter = require('./modules');
console.log(Counter()); // 出力結果：{ Counter: [Function: Counter] }

// パターン2
const Counter = require('./modules');
console.log(Counter.Counter()); // 出力結果：counter text

// パターン3
const { Counter } = require('./modules');
console.log(Counter()); // 出力結果：counter text
```

# 参考リンク

[Node.js でのモジュールとエクスポートの方法](https://nodejs.keicode.com/nodejs/module-exports.php)
[Node.js の exports と module.exports](https://www.webdesignleaves.com/pr/jquery/node-js-module-exports.html)
[モジュール化(importとrequireの違い)](https://www.wakuwakubank.com/posts/466-javascript-module-import-export/)