💭

JavaScript、TypeScriptのモジュール分割について整理してみた

2022/07/03に公開

JavaScriptなのかTypeScriptなのか、またはモジュールバンドラー(webpackなど)の機能が使われているのかをちゃんと理解していなかったので整理

JavaScript

importを使わない

ファイルの依存関係、読み込み順序を開発者が管理する必要がある

html
<script src="./bar.js" defer></script>
<script src="./foo.js" defer></script>
<script src="./index.js" defer></script>
javascript
// index.js
console.log(foo);

// foo.js
const foo = bar;

// bar.js
const bar = "bar";

importを使う

ファイルの依存関係、読み込み順序を開発者が管理する必要がない。ただし、importごとにhttpリクエストが発生するので遅延が発生する

javascript
// index.js
import { foo } from "./foo.js";
console.log(foo);

// foo.js
import { bar } from "./bar.js";
export const foo = bar;

// bar.js
export const bar = "foo";
html
<script src="./index.js" type="module"></script>

モジュールバンドラーを使ったimport

ファイルの依存関係、読み込み順序を開発者が管理する必要がない。また、htmlが読み込むファイルはモジュールバンドラー(webpackなど)によってバンドル(1ファイルにまとめる)されたファイルのためimportごとにhttpリクエストが発生しない

javascript
// index.js
import { foo } from "./foo";
console.log(foo);

// foo.js
import { bar } from "./bar"
export const foo = bar;

// bar.js
export const bar = "bar";
html
<script src="./bundle.js"></script>

TypeScript

名前空間を使う

名前空間(namespace)と<reference path />を指定する方法。依存関係と読み込み順を開発者が管理する必要がある

typescript
// index.ts
/// <reference path="./foo.ts" />
console.log(Foo.foo);

// foo.ts
/// <reference path="./bar.ts" />
namespace Foo {
  export const foo = Bar.bar;
}

// bar.ts
namespace Bar {
  export const bar = "bar";
}
html
<script src="./bar.js" defer></script>
<script src="./foo.js" defer></script>
<script src="./index.js" defer></script>
tsconfig.json
{
    "module": "amd",
    ・・・
}

名前空間とバンドル

tsconfig.jsonでoutFileを指定してTypeScriptのバンドル機能を有効にする。依存関係を開発者が管理する必要がある

typescript
// index.ts
/// <reference path="./foo.ts" />
console.log(Foo.foo);

// foo.ts
/// <reference path="./bar.ts" />
namespace Foo {
  export const foo = Bar.bar;
}

// bar.ts
namespace Bar {
  export const bar = "bar";
}
html
<script src="./bundle.js"></script>
tsconfig.json
{
    "module": "amd",
    "outFile": "bundle.js",
    ・・・
}

importを使う

ファイルの依存関係、読み込み順序を開発者が管理する必要がない。ただし、importごとにhttpリクエストが発生するので遅延が発生する

typescript
// index.ts
import { foo } from "./foo.js";
console.log(foo);

// foo.ts
import { bar } from "./bar.js";
export const foo = bar;

// bar.ts
export const foo = bar;
html
<script src="./index.js" type="module"></script>
tsconfig.json
{
    "module": "es6",
    ・・・
}

モジュールバンドラーを使ったimport

ファイルの依存関係、読み込み順序を開発者が管理する必要がない。また、htmlが読み込むファイルはモジュールバンドラー(webpackなど)によってバンドル(1ファイルにまとめる)されたファイルのためimportごとにhttpリクエストは発生しない

typescript
// index.ts
import { foo } from "./foo";
console.log(foo);

// foo.ts
import { bar } from "./bar";
export const foo = bar;

// bar.ts
export const foo = bar;
html
<script src="./bundle.js"></script>

おわりに

JavaScript、TypeScriptともにモジュールバンドラーを使ってimportするのがプログラムが書きやすく、httpリクエストの回数を抑えることができる

Discussion