Script / モジュール / CommonJS / ES Modules って、どんなふうに違うのかな?
今回は JavaScript の Script / モジュール / CommonJS / ES Modules について取り上げてみたい思います。
Script とは?
Script とは従来の JavaScript の仕組みで、HTML 上で JavaScript を実行するために <script> タグを使って直接コードを書いたり、外部ファイルを読み込んだりする方法のこと です。
Script では、コードがグローバルスコープに置かれる ため、ファイル間の仕切りがなく、変数や関数の名前が衝突しやすいといった問題 があり、大きなアプリでは管理が難しくなってしまいます。
// index.html
// HTML に JavaScript を読み込ませる
<script src="app.js"></script>
Script(従来のJavaScript)の特徴と問題点まとめ
| 特徴 | 具体的な内容 | その結果起きる問題 |
|---|---|---|
| グローバルスコープ | 変数や関数がすべて window に登録される | 変数名が衝突しやすい(上書き事故) |
| ファイル間の独立性がない | どのファイルも同じ空間を共有 | 他のファイルの影響を受けやすい |
| 読み込み順に依存 | <script> の順番で実行される | 順番を間違えるとエラーになる |
| 依存関係が明示できない | 「このファイルは何に依存しているか」書けない | コードの見通しが悪い |
| 再利用しにくい | 機能単位で分離しづらい | 大規模開発に不向き |
| strict modeが自動で有効にならない | 明示的に "use strict" が必要 | バグに気づきにくい |
// ❌ NG app.js の中で math.js の関数を使っていた場合、上から読み込むためエラー
<script src="app.js"></script>
<script src="math.js"></script>
// 変数や関数がすべて window に登録されるため、どちらかが上書きされてしまう
// file1.js
var count = 0;
// file2.js
var count = 100;
Script は、小規模なページでは問題ありませんが、機能が増えてファイル数が多くなったり、複数人で開発するようになると、同じ名前の変数がかぶってしまったり、どの順番で読み込めばよいのか分からなくなったりするといった問題 が起きやすくなります。
こうした問題を解決し、ファイルごとに役割を分けて、コードを整理しやすくするために生まれたのが、モジュール という仕組みです。
モジュール とは?
モジュール とは、プログラムを整理するため に、機能ごとに分けた部品(ファイル)のことです。
モジュールの目的
| 目的 | 説明 |
|---|---|
| 整理する | 機能ごとにファイルを分けて読みやすくする |
| 再利用する | 他のファイルから必要な機能だけを使えるようにする |
| 衝突を防ぐ | ファイルごとにスコープが分かれるため、同じ名前の変数があっても影響しない |
スコープの例(ファイルごとに独立)
ファイルごとにスコープ(変数の範囲)が分かれている ため、同じ名前でも衝突しない
// math.js
const count = 0;
// user.js
const count = 100;
モジュールの使用例
ファイルごとにスコープ(変数の範囲)が分かれている ため、同じ名前でも衝突しない
// math.js ※ 計算用のファイル
export function add(a, b) {
return a + b;
}
// app.js
// math.js から必要な機能(add)だけを読み込む
import { add } from "./math.js";
console.log(add(2, 3)); // 5
モジュールのメリット
- 機能ごとにファイルを分けて整理できる ことで、コードが読みやすくなる
- ファイルごとにスコープ(適用範囲)が分割される ため、同じ名前の変数があっても衝突せずに安全に管理 できる
- 他のファイルから必要な機能だけを外に出して (
export) 使える (import)ようにでき、再利用しやすい - コードの整理・再利用・安全性の確保ができる
CommonJS とは?
CommonJS とは、Node.js で モジュールを扱うために作られた仕組みのこと で、React.js では直接使いませんが、サーバーサイドの JavaScript や 古いNode.jsパッケージ では、今でもよく見かけます。
背景
JavaScript はもともとブラウザの Script しかなく、ファイルを分けても ファイル同士の依存関係を管理することができません でした。
Node.js がサーバー上で JavaScript を使えるようになったとき、大規模な開発では どのファイルがどの機能を使うのかを整理する仕組み(モジュール) が必要になりました。
そこで作られたのが CommonJSです。
コード例
モジュールの作成(export)
// math.js
function add(a, b) {
return a + b;
}
function subtract(a, b) {
return a - b;
}
// このファイルから外に出す
module.exports = { add, subtract };
モジュールの利用(import)
// app.js
const math = require("./math");
console.log(math.add(2, 3)); // 5
console.log(math.subtract(5, 2)); // 3
特徴
| 項目 | 説明 |
|---|---|
| 書き方 | module.exports(出力する)require() (読み込む) |
| 読み込みタイミング | 実行時に読み込む(動的) |
| 環境 | Node.js が中心(ブラウザでは直接使えない) |
| メリット | サーバー上でファイルを分割・機能の再利用が可能 |
| 注意点 | 静的解析ができないので、ツールによる最適化が難しい |
ES Modules とは?
ES Modules とは、機能ごとに分けたファイル(モジュール)を、安全に分割・再利用できるようにした JavaScript の公式な仕組み です。
特徴として、ブラウザと Node.js の両方で使う ことができ、React.js や Vue.js などの モダンなフロントエンド開発で標準的に使用 されています。
named export コード例
named export は、複数の機能をまとめてエクスポートする ときによく使用されます。
インポート時には { } が必要で、基本的には同じ名前を使用します
※ as を使用した場合、別名(alias)として名前の変更が可能
モジュールの作成(export)
// math.js
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
モジュールの利用(import)
// app.js
// subtract を別名(alias)として minus として import
import { add, subtract as minus } from "./math.js";
console.log(add(2, 3)); // 5
console.log(minus(5, 2)); // 3
default エクスポート
export default は、1つのモジュールにつき1つだけエクスポートでき、インポート側では自由な名前を付けることができます。 ※ { } は不要 です。
※ default は、このモジュールの代表となる1つの機能をエクスポートする ときによく使われます。
モジュールの作成(export)
// greet.js
export default function greet(name) {
return `Hello, ${name}!`;
}
モジュールの利用(import)
// app.js
// greet を greetHello として import
import greetHello from "./greet.js";
console.log(greetHello("Taro")); // Hello, Taro!
特徴
| 特徴 | 説明 |
|---|---|
| 書き方 | export / export default(出力する)import(読み込む) |
| 読み込みタイミング | 静的に読み込む(コンパイル時に依存関係が分かる) |
| 環境 | ブラウザ + Node.js(モダン環境) |
| メリット | ・コードを整理・再利用しやすい ・静的解析が可能でツールによる最適化がしやすい ・React.js やモダンフロントエンドの標準 |
| 注意点 | 古い Node.js パッケージや古いブラウザでは使えない場合がある |
CommonJS と ES Modules の違い
CommonJS と ES Modules では、下記のような違いがあります
| 比較 | CommonJS | ES Modules |
|---|---|---|
| 書き方 | require() / module.exports | import / export |
| 読み込み | 実行時(動的) | 静的(コンパイル時に依存関係が分かる) |
| 環境 | Node.js | ブラウザ + Node.js |
| React.js や Vue.js での使用 | ほぼなし | 標準 |
React.js や Vue.js の場合
React.js や Vue.js などのモダンなフロントエンド開発では、モジュールを扱う際に ES Modules(import / export) を基本的に使います。
これは JavaScript の 公式仕様 であり、コードの分割・再利用・可読性の向上 にも役立ちます
まとめ
JavaScript の Script / モジュール / CommonJS / ES Modules について解説してきましたが、いかがでしたでしょうか?
従来の Script は <script> タグでコードを読み込み、すべてが同じグローバル空間で動く仕組み だったため、複数ファイルの管理や名前の衝突が起きやすいという問題 がありました。
その問題を解決するために、機能ごとにファイルを分けて必要な機能だけを再利用できる仕組み(モジュール) という考え方が生まれました。
CommonJS はその モジュール を Node.js で扱うためにつくられた仕組みで、サーバーサイドの JavaScript で長く使用されてきました。
現在は JavaScript の公式仕様として定められ、ブラウザと Node.js の両方で使える ES Modules が主流になっています
React.js や Vue.js などの モダンなフロントエンド開発 でも ES Modules が標準的に使われているため、ES Modules を理解して効率的な開発を進めていきましょう。


コメント