【JavaScript/TypeScript】import/export from使い方まとめ

import fromとexport from、よく分からなくなるのでまとめました。

## ファイル関係図

### 登場人物

- `child1.ts`, `child2.ts` - 【子モジュール】メインプログラムで使える変数をexportする
- `parent.ts` - 【親モジュール】小モジュール２つをまとめてexportし直す
- `main.ts` - 【メインプログラム】親モジュールをimportして使う

### 関係図

左が右を読み込む。

  　↓(実行主体)
`main.ts` ← `parent.ts` ← `child1.ts`
　　　　　　　　　　　　　← `child2.ts`

## 子モジュール定義
```typescript
// child1.ts
export const hoge = 'hoge'
export const fuga = 'fuga'
export default 'default1'
// child2.ts
export const foo = 'foo'
export const bar = 'bar'
export default 'default2'
```

## 使い方

### `import { ... }` - 選択したnamed exportそれぞれを変数で受け取る
```typescript
// parent.ts
import { hoge } from './child1'
import { foo } from './child2'
console.log(hoge, foo) // hoge foo
export { hoge, foo }

// main.ts
import { hoge, foo } from './parent'
console.log(hoge, foo) // hoge foo
```

### `export { ... }` - 選択したnamed exportそれぞれをそのままnamed export
```typescript
// parent.ts
export { hoge } from './child1'
export { foo } from './child2'

// main.ts
import { hoge, foo } from './parent'
console.log(hoge, foo) // hoge foo
```

### `export *` - named export全体をそのままnamed export
```typescript
// parent.ts
export * from './child1'
export * from './child2'

// main.ts
import { hoge, fuga, foo, bar } from './parent'
console.log(hoge, fuga, foo, bar) // hoge fuga foo bar
```

【注意】defaultは対象外。


### `import ...` - default exportを変数で受け取る
```typescript
// parent.ts
export * from './child1'
export * from './child2'
import default2 from './child2'
console.log(default2) // default2
export default default2

// main.ts
import default2, { hoge, fuga, foo, bar } from './parent'
console.log(hoge, fuga, foo, bar, default2) // hoge fuga foo bar default2
```

### `export { default }` - default exportをそのままdefault export
```typescript
// parent.ts
export * from './child1'
export * from './child2'
export { default } from './child2'

// main.ts
import default2, { hoge, fuga, foo, bar } from './parent'
console.log(hoge, fuga, foo, bar, default2) // hoge fuga foo bar default2
```

### `export { default as <alias> }` - default exportをnamed exportしなおす
```typescript
// parent.ts
export * from './child1'
export { default as default1 } from './child1'
export * from './child2'
export { default as default2 } from './child2'

// main.ts
import { hoge, fuga, foo, bar, default2 } from './parent'
console.log(hoge, fuga, default1, foo, bar, default2) // hoge fuga default1 foo bar default2
```

### `import * as <alias>` - export全体を変数で受け取る
```typescript
// parent.ts
import * as child1 from './child1'
import * as child2 from './child2'
console.log(child1, child2) // { hoge: 'hoge', fuga: 'fuga', default: 'default1' } { foo: 'foo', bar: 'bar', default: 'default2' }
export { child1, child2 }

// main.ts
import { child1, child2 } from './parent'
console.log(
  child1.hoge,
  child1.fuga,
  child1.default,
  child2.foo,
  child2.bar,
  child2.default,
) // hoge fuga default1 foo bar default2
```

### `export * as <alias>` - export全体をnamed exportしなおす
```typescript
// parent.ts
export * as child1 from './child1'
export * as child2 from './child2'

// main.ts
import { child1, child2 } from './parent'
console.log(
  child1.hoge,
  child1.fuga,
  child1.default,
  child2.foo,
  child2.bar,
  child2.default,
) // hoge fuga default1 foo bar default2
```

# 参考

上記の合わせ技・抜け漏れ等は以下の公式ドキュメントからどうぞ
- https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/import
- https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/export

Barrel export（`parent.ts`の役割をそう呼ぶらしい）
- https://typescript-jp.gitbook.io/deep-dive/main-1/barrel