Javascript/Node.jsのimportやらrequireやらのまとめ


JavascriptとNode.jsを行ったり来たりしていると、import、export、exports、require、module、defaultの単語が頭の中でぐちゃぐちゃになりがちです。
備忘録として、使い方を残しておきます。

ちなみに、Javascriptにおいて、webpackやbrowserify、babelといったbundlerを使ったrequireの使用は述べていません。純粋なNode.jsや、ブラウザ上のJavascript上での動作を想定しています。

# Javascript編

## import/exportを使わない方法

① インラインスクリプト

```html:index.html
	<script type="text/javascript">
		class Test1 {
		  test(param){
		    console.log('Test1.test(' + param + ') called');
		  }
		}
	</script>
    <script src="js/start.js"></script>
```

```js:js/start.js
var test1 = new Test1();
test1.test('hello1');
```

② 別ファイル化

```js:js/Test2.js
class Test2{
  test(param){
    console.log('Test2.test(' + param + ') called');
  }
}
```

```html:index.html
<script src="js/Test2.js"></script>
<script src="js/start.js"></script>
```


```js:js/start.js
var test2 = new Test2();
test2.test('hello2');
```

## import/exportを使う場合

※importを使う場合は、ブラウザから直接ファイルを読み込むことはできず、Webサーバにデプロイしてからロードする必要がある。
※importされたモジュールは、importを呼び出したモジュール内でのみ利用可能(後述のグローバル化を除く)。
※htmlにscript宣言する場合、type=”module”を付ける必要あり

①パターン１(公開オブジェクトが1つのみ)

```js:js/Test4.js
export default class Test4{
  test(param){
    console.log('Test4.test(' + param + ') called');
  }
}
```

```html:index.html
<script src="js/start.js" type="module"></script>
```

```js:js/start.js
import Test4 from './Test4.js';
var test4 = new Test4();
test4.test('hello1');
```

②パターン２(複数のオブジェクトを公開)

```js:js/Test5.js
export class Test5{
  test(param){
    console.log('Test5.test(' + param + ') called');
  }
}
```

```html:index.html
<script src="js/start.js" type="module"></script>
```

```js:js/start.js
import { Test5 } from './Test5.js';
var test5 = new Test5();
test5.test('hello2');
```

または

```js:js/start.js
import * as Test from './Test5.js';
var test5 = new Test.Test5();
test5.test('hello3');
```


③グローバル化（importを使わずにexportを使う場合）

※グローバルオブジェクトwindowにつけることで、どこからでも参照可能となる

```js:js/Test6.js
export class Test6{
  test(param){
    console.log('Test6.test(' + param + ') called');
  }
}

if( typeof window !== 'undefined' )
  window.Test6 = Test6;
```

```html:index.html
<script src="js/Test6.js" type="module"></script>
<script src="js/start.js" type="module"></script>
```

```js:js/start.js
var test6 = new Test6();
test6.test('hello4');
```

④グローバル化（既存のexportモジュールのグローバル化）

※以下、既存のexportモジュール「Test5.js」をグローバル化する例

```js:js/Test7.js
import { Test5 } from './Test5.js';

if( typeof window !== 'undefined' )
  window.Test7 = Test5;
```

```html:index.html
<script src="js/Test7.js" type="module"></script>
<script src="js/start.js" type="module"></script>
```

```js:js/start.js
var test7 = new Test7();
test7.test('hello5');
```

## import/exportを使わないモジュールからexportモジュールを利用

※既出のexportモジュール「Test6.js」を利用の場合の例
※htmlに宣言する場合、type="module"を付けないで宣言すると、type="module"よりも先にロードしようとするため、deferをつける

```html:index.html
<script src="js/Test6.js" type="module"></script>
<script src="js/start.js" defer></script>
```

```js:js/start.js
var test6 = new Test6();
test6.test('hello1');
```

※既出のexportモジュール「Test7.js」を利用の場合も同様

```html:index.html
<script src="js/Test7.js" type="module"></script>
<script src="js/start.js" defer></script>
```

```js:js/start.js
var test7 = new Test7();
test7.test('hello2');
```

# Node.js編

## requireの場合

①同一ファイル内

```js:index.js
class Test1 {
  test(param){
    console.log('Test1.test(' + param + ') called');
  }
}

var test1 = new Test1();
test1.test('hello1');
```

②別ファイル化(公開オブジェクトが1つのみ)

```js:Test2.js
class Test2{
  test(param){
    console.log('Test2.test(' + param + ') called');
  }
}

module.exports = Test2;
```

```js:index.js
const Test2 = require('./Test2.js')
var test2 = new Test2();
test2.test('hello2');
```

③別ファイル化(複数のオブジェクトを公開)

```js:Test3.js
class Test3{
  test(param){
    console.log('Test3.test(' + param + ') called');
  }
}

exports.Test3 = Test3;
```

```js:index.js
const { Test3 } = require('./Test3.js')
var test3 = new Test3();
test3.test('hello3');
```

## importの場合

※ファイル拡張子をmjsにする

①外部ファイル化(公開オブジェクトが1つのみ)

```js:Test4.mjs
console.log('Test4 loading');

export default class Test4{
  test(param){
    console.log('Test4.test(' + param + ') called');
  }
}
```

```js:index.mjs
import Test4 from './Test4.mjs';
var test4 = new Test4();
test4.test('hello1');
```

②外部ファイル化(複数のオブジェクトを公開)

```js:Test5.mjs
console.log('Test5 loading');

export class Test5{
  test(param){
    console.log('Test5.test(' + param + ') called');
  }
}
```

```js:index.mjs
import { Test5 } from './Test5.mjs';
var test5 = new Test5();
test5.test('hello2');
```

以上