基礎から学ぶJavaScript入門 90日コース | 実践的なJavaScript - Day 71:ES Modules

JavaScript 90日で身につけるJavaScript
スポンサーリンク
スポンサーリンク

Day 71:ES Modules

Day 71では、第6フェーズ「実践的なJavaScript」の入口として、ES Modulesを学びます。今回の学習内容は、export、import、そして実践としてのファイル分割です。ここまでの学習では、変数、関数、条件分岐、繰り返し、配列、オブジェクト、DOM操作、イベント処理、非同期処理、APIなど、JavaScriptの基本機能を1つずつ積み上げてきました。ここから第6フェーズでは、それらの知識を「より整理された書き方」「より実践的な設計」へ進めていきます。その最初の大きなテーマがES Modulesです。

初心者の方がこれまで書いてきたコードは、1つのHTMLファイルや1つのJavaScriptファイルにすべてまとめる形が多かったはずです。学習初期ではそれで問題ありません。むしろ最初は1か所にまとまっていたほうが流れを追いやすいからです。しかし、コード量が増えてくると、1ファイルに全部書く方法には限界が出てきます。どこに何があるのか探しにくくなり、同じような処理が散らばりやすくなり、修正もしにくくなります。そこで必要になるのが、役割ごとにファイルを分け、それらをつなぐ仕組みです。それを実現するのがES Modulesです。

今回のポイントは、「難しい新機能を覚える」というより、「これまで書いてきたコードを、もっと整理しやすい形に変える」ということです。つまりDay 71は、JavaScriptの能力を一気に増やす回というより、コードのまとめ方をレベルアップする回です。初心者の方は、ここでファイル分割の考え方を理解しておくと、この先のアプリ開発でコードがかなり見やすくなります。今回は、ES Modulesとは何か、export と import は何をしているのか、なぜファイル分割が必要なのか、どんな分け方をすればよいのか、どこでつまずきやすいのかまで、ステップバイステップで丁寧に説明していきます。

まず最初に結論をつかむ

最初に今回の内容を一言でまとめると、ES Modulesとは「JavaScriptの機能をファイルごとに分けて、必要なものだけを他のファイルで読み込める仕組み」です。

今回の基本の流れは次の通りです。

  • あるファイルで関数や変数を作る
  • `export` を使って外へ出せるようにする
  • 別のファイルで `import` を使って読み込む
  • 役割ごとにファイルを分割する

初心者の方は、まず export は「渡す」、import は「受け取る」と考えると理解しやすいです。

ES Modulesとは何か

ES Modulesは、JavaScriptのコードをモジュール単位で分ける仕組みです。ここでいうモジュールとは、簡単に言えば「役割を持った1つの部品」です。たとえば、計算だけを担当するファイル、画面表示だけを担当するファイル、データ取得だけを担当するファイル、というように分けられます。

初心者の方は、モジュールという言葉を難しく感じるかもしれませんが、まずは「ファイルごとに仕事を分けた部品」くらいの理解で十分です。つまり、ES Modulesは「JavaScriptを部品化して整理する仕組み」だと考えるとわかりやすいです。

なぜES Modulesが必要なのか

ここはDay 71で特に重要な部分です。なぜES Modulesが必要なのかというと、コードが増えてきたときに、1つのファイルに全部書くのがつらくなるからです。

たとえば、次のような問題が起きやすくなります。

  • 関数が増えすぎて、どこに何があるかわかりにくい
  • 画面表示の処理と計算処理が混ざって読みにくい
  • 同じような機能を別の場所でも使いたいのに再利用しにくい
  • 複数人で開発するときに役割分担しづらい
  • 変数名や関数名がぶつかりやすい

初心者の方は、最初は「分ける必要あるのかな」と思うこともあります。しかし、小さなコードでも少しずつ整理していく習慣をつけておくと、後から非常に楽になります。

ファイル分割の考え方

ファイル分割では、何を基準に分けるかが大切です。適当に分けるとかえってわかりにくくなります。基本は「役割ごとに分ける」です。

たとえば、次のような分け方があります。

  • 計算処理をまとめた `math.js`
  • 画面表示をまとめた `ui.js`
  • 全体の実行をまとめた `app.js`

初心者の方は、最初から細かく分けすぎる必要はありません。まずは「計算」「表示」「実行」くらいの大きな分け方で十分です。大切なのは、同じ種類の処理を同じ場所に集めることです。

exportとは何か

export は、そのファイルの中で作った関数や変数を、他のファイルでも使えるように外へ出すための書き方です。

たとえば、math.js に次のような関数があるとします。

// 2つの数を足す関数を外へ出せるようにする
export function add(a, b) {
  return a + b;
}
JavaScript

この export があることで、別のファイルから add() を読み込めるようになります。

初心者の方は、export を「この関数は他のファイルでも使っていいですよと公開する印」と考えると理解しやすいです。

importとは何か

import は、他のファイルで export されたものを読み込むための書き方です。

たとえば、先ほどの math.js にある add() を app.js で使うなら、次のように書きます。

// math.js から add 関数を読み込む
import { add } from "./math.js";

console.log(add(2, 3));
JavaScript

ここで大切なのは、import するときに { add } と波かっこを使っていることと、ファイルパスを "./math.js" のように書いていることです。

初心者の方は、import を「必要な部品を別ファイルから持ってくる」と考えると整理しやすいです。

まずは最小の例で流れをつかむ

いきなり大きなアプリで考えると難しいので、まずは最小の例で流れをつかみます。

greet.js

// あいさつを返す関数を外へ出せるようにする
export function greet(name) {
  return `こんにちは、${name}さん`;
}
JavaScript

app.js

// greet.js から greet 関数を読み込む
import { greet } from "./greet.js";

// 関数を使って結果を表示する
console.log(greet("JavaScript"));
JavaScript

この2ファイルだけでも、ES Modulesの基本は入っています。

  • `greet.js` で関数を作る
  • `export` で公開する
  • `app.js` で `import` する
  • 読み込んだ関数を使う

初心者の方は、まずこの最小の流れを完全に理解することが大切です。

名前付きエクスポートとデフォルトエクスポート

ES Modulesには export の書き方が2種類あります。初心者の方はまず名前付きエクスポートを中心に覚えるのがおすすめです。

  • 名前付きエクスポート
  • デフォルトエクスポート

まずは名前付きエクスポートです。

// 名前付きで関数をエクスポートする
export function add(a, b) {
  return a + b;
}

export function subtract(a, b) {
  return a - b;
}
JavaScript

読み込む側はこう書きます。

// 波かっこを使って必要な関数を読み込む
import { add, subtract } from "./math.js";

console.log(add(10, 5));
console.log(subtract(10, 5));
JavaScript

この形は、1つのファイルから複数の部品を読み込みやすいです。初心者の方は、まずこの名前付きエクスポートを基本にするのがわかりやすいです。

デフォルトエクスポートとは何か

一方、デフォルトエクスポートは、そのファイルの「代表となる1つ」を出すイメージです。

// 1つの関数をデフォルトとしてエクスポートする
export default function greet(name) {
  return `こんにちは、${name}さん`;
}
JavaScript

読み込む側はこう書きます。

// デフォルトエクスポートは波かっこなしで読み込む
import greet from "./greet.js";

console.log(greet("太郎"));
JavaScript

初心者の方が最初に混乱しやすいのは、名前付きエクスポートでは波かっこが必要で、デフォルトエクスポートでは不要という点です。そのため、学習初期はまず名前付きエクスポートを中心に練習するのがおすすめです。

初心者にはどちらがおすすめか

初心者の方には、まず名前付きエクスポートがおすすめです。理由は、何を出していて何を読み込んでいるかが見えやすいからです。

  • 名前付きエクスポートは、何を読み込むか明示しやすい
  • 複数の関数を1ファイルにまとめやすい
  • 波かっこが必要なので、どこが読み込み対象か見分けやすい

デフォルトエクスポートも便利ですが、最初は「1ファイル1機能」と思い込みすぎたり、名前付きとの違いで混乱したりしやすいです。まずは名前付きから慣れるのが安全です。

ステップ1:1つのファイルに書いていたコードを見直す

ここから実践です。たとえば、これまで次のように1ファイルへ全部まとめていたとします。

// 数字を足す関数
function add(a, b) {
  return a + b;
}

// 画面に結果を表示する関数
function showResult(value) {
  const result = document.getElementById("result");
  result.textContent = `結果: ${value}`;
}

// 実行処理
const total = add(3, 7);
showResult(total);
JavaScript

このままでも動きますが、役割が混ざっています。

  • 計算の関数
  • 画面表示の関数
  • 実行の流れ

初心者の方は、まず「このコードにはどんな役割が含まれているか」を見分けることが、ファイル分割の第一歩です。

ステップ2:役割ごとにファイルを分ける

上のコードを、次のように分けてみます。

  • `math.js` に計算処理を書く
  • `ui.js` に画面表示を書く
  • `app.js` に全体の流れを書く

math.js

// 数字を足す関数を外へ出せるようにする
export function add(a, b) {
  return a + b;
}
JavaScript

ui.js

// 画面に結果を表示する関数を外へ出せるようにする
export function showResult(value) {
  const result = document.getElementById("result");
  result.textContent = `結果: ${value}`;
}
JavaScript

app.js

// math.js から add 関数を読み込む
import { add } from "./math.js";

// ui.js から showResult 関数を読み込む
import { showResult } from "./ui.js";

// 計算して表示する
const total = add(3, 7);
showResult(total);
JavaScript

この形にすると、役割がかなりはっきりします。初心者の方は、「どのファイルが何を担当しているか」を一目で説明しやすくなる点に注目するとよいです。

ステップ3:HTML側でモジュールとして読み込む

ES Modulesをブラウザで使うときは、HTMLの script タグに type="module" を付ける必要があります。ここは非常に重要です。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>ES Modules 練習</title>
</head>
<body>
  <p id="result">ここに結果が表示されます。</p>

  <!-- app.js をモジュールとして読み込む -->
  <script type="module" src="./app.js"></script>
</body>
</html>

もし type="module" を付け忘れると、import や export が使えずエラーになります。初心者の方が非常につまずきやすいポイントなので、ここは必ず覚えておく必要があります。

なぜscriptタグにtype=”module”が必要なのか

これはブラウザに対して、「このJavaScriptは普通のスクリプトではなく、モジュールとして扱ってください」と伝えるためです。ブラウザはこの指定があることで、import や export を理解し、ファイル同士の読み込み関係を処理できるようになります。

初心者の方は、type="module" を「ES Modulesを有効にするスイッチ」と考えると覚えやすいです。

ステップ4:ファイルパスの書き方に慣れる

ES Modulesでは、import のときにファイルパスを正しく書く必要があります。ここも初心者の方がよくつまずくポイントです。

import { add } from "./math.js";
JavaScript

この "./math.js" には意味があります。

  • `./` は「同じフォルダの中」を表す
  • `math.js` は対象ファイル名

たとえば、js/modules/math.js のように別フォルダなら、パスも変わります。

import { add } from "./modules/math.js";
JavaScript

初心者の方は、「ファイルを分けたら、どこにあるかを正しく伝えないと読み込めない」と理解しておくことが大切です。

拡張子 .js を省略しないことが重要

ブラウザでES Modulesを使うときは、ファイル名の .js を省略しないほうが安全です。むしろ初心者の段階では「必ず書く」と覚えておくのがおすすめです。

// 良い例
import { add } from "./math.js";
JavaScript
// 初心者には非推奨な例
import { add } from "./math";
JavaScript

環境によっては省略形が動かないことがあります。初心者の方は、「モジュール読み込みでは拡張子まで書く」と習慣化しておくとトラブルが減ります。

ステップ5:複数の関数をまとめてエクスポートする

1つのファイルに複数の関数をまとめることもできます。

math.js

// 足し算
export function add(a, b) {
  return a + b;
}

// 引き算
export function subtract(a, b) {
  return a - b;
}

// 掛け算
export function multiply(a, b) {
  return a * b;
}
JavaScript

app.js

// math.js から複数の関数を読み込む
import { add, subtract, multiply } from "./math.js";

console.log(add(5, 2));
console.log(subtract(5, 2));
console.log(multiply(5, 2));
JavaScript

この形にすると、同じ種類の処理を1つのファイルへまとめられます。初心者の方は、「同じ仲間の関数をひとまとめにする」感覚を持つと整理しやすいです。

実践例:簡単なアプリをファイル分割する

ここではもう少し実践的に、入力値を足し算して結果を表示する小さなアプリを、モジュール分割して作ってみます。

まずHTMLです。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Day 71 ES Modules</title>
</head>
<body>
  <h2>足し算アプリ</h2>

  <input type="number" id="num1" placeholder="1つ目の数字">
  <input type="number" id="num2" placeholder="2つ目の数字">
  <button id="calcButton">計算する</button>

  <p id="result">ここに結果が表示されます。</p>

  <!-- モジュールとして app.js を読み込む -->
  <script type="module" src="./app.js"></script>
</body>
</html>

次に math.js です。

// 足し算を行う関数をエクスポートする
export function add(a, b) {
  return a + b;
}
JavaScript

次に ui.js です。

// 結果を画面に表示する関数をエクスポートする
export function showResult(value) {
  const result = document.getElementById("result");
  result.textContent = `結果: ${value}`;
}
JavaScript

最後に app.js です。

// 計算用の関数を読み込む
import { add } from "./math.js";

// 画面表示用の関数を読み込む
import { showResult } from "./ui.js";

// 必要なHTML要素を取得する
const num1Input = document.getElementById("num1");
const num2Input = document.getElementById("num2");
const calcButton = document.getElementById("calcButton");

// ボタンが押されたときの処理
calcButton.addEventListener("click", function () {
  // 入力値を数値に変換する
  const num1 = Number(num1Input.value);
  const num2 = Number(num2Input.value);

  // 足し算を実行する
  const total = add(num1, num2);

  // 結果を表示する
  showResult(total);
});
JavaScript

この例では、かなり実践的なファイル分割ができています。

  • `math.js` は計算担当
  • `ui.js` は表示担当
  • `app.js` は全体の制御担当

初心者の方は、この役割分担がES Modulesの基本的な考え方だと理解するとよいです。

ファイル分割のメリットを整理する

ここで、なぜファイル分割が便利なのかをあらためて整理します。

  • コードの役割がはっきりする
  • 必要な場所だけ探しやすい
  • 同じ機能を別のファイルでも再利用しやすい
  • 修正の影響範囲が見えやすい
  • 複数人での開発にも向いている

初心者の方は、特に「探しやすさ」と「再利用しやすさ」の2つを実感しやすいはずです。コード量が増えるほど、このメリットは大きくなります。

情報セキュリティの観点でのメリット

ES Modulesやファイル分割は、情報セキュリティの視点でも意味があります。もちろん、モジュール化しただけで自動的に安全になるわけではありません。しかし、コードの役割が分かれていると、どこで入力を受け取り、どこで表示し、どこで計算しているかが見えやすくなります。これは安全確認のしやすさにつながります。

たとえば、次のような点で役立ちます。

  • 外部入力を扱う部分を見つけやすい
  • DOMへ表示する部分を分離しやすい
  • 危険な処理がどこにあるか確認しやすい
  • 不要なグローバル変数を減らしやすい

初心者の方は、「整理されたコードは、安全確認もしやすい」と考えると理解しやすいです。

グローバル汚染を防ぎやすい

ここも重要です。1つのファイルにすべてを書いていると、変数や関数が広い範囲で見えてしまい、名前の衝突が起きやすくなります。これをグローバル汚染と呼ぶことがあります。ES Modulesでは、モジュールごとにスコープが分かれるため、意図せず他のファイルに影響を与えにくくなります。

初心者の方は、「ファイルを分けると、関係ない場所に勝手に影響しにくくなる」と考えるとわかりやすいです。

初心者がつまずきやすいポイント

Day 71では、次のような点でつまずきやすいです。

  • `script` タグに `type=”module”` を付け忘れる
  • `import` のパスが間違っている
  • `.js` の拡張子を書いていない
  • 名前付きエクスポートなのに波かっこを書いていない
  • デフォルトエクスポートなのに波かっこを書いている
  • ファイル名の大文字小文字が一致していない

特に、ファイルパスと type="module" は本当によくあるミスです。初心者の方は、エラーが出たらまずこの2つを先に確認するとよいです。

ローカルファイルを直接開くと動かないことがある

これもとても大切です。ES Modulesは、環境によってはHTMLファイルを直接ダブルクリックして開いただけではうまく動かないことがあります。その場合はローカルサーバーを使います。

たとえば、Visual Studio CodeのLive Serverなどを使うと確認しやすいです。初心者の方は、「モジュールはローカルサーバーで動かすと安定しやすい」と覚えておくとよいです。

そのまま使える学習用テンプレート

ここでは、Day 71の学習内容をまとめた、最小で実用的なテンプレートを紹介します。

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Day 71 ES Modules</title>
</head>
<body>
  <h2>ES Modules 練習</h2>

  <input type="number" id="num1" placeholder="1つ目の数字">
  <input type="number" id="num2" placeholder="2つ目の数字">
  <button id="calcButton">足し算する</button>

  <p id="result">ここに結果が表示されます。</p>

  <!-- app.js をモジュールとして読み込む -->
  <script type="module" src="./app.js"></script>
</body>
</html>

math.js

// 足し算を行う関数をエクスポートする
export function add(a, b) {
  return a + b;
}
JavaScript

ui.js

// 結果を表示する関数をエクスポートする
export function showResult(value) {
  const result = document.getElementById("result");
  result.textContent = `結果: ${value}`;
}
JavaScript

app.js

// math.js から add 関数を読み込む
import { add } from "./math.js";

// ui.js から showResult 関数を読み込む
import { showResult } from "./ui.js";

// 必要な要素を取得する
const num1Input = document.getElementById("num1");
const num2Input = document.getElementById("num2");
const calcButton = document.getElementById("calcButton");

// ボタンが押されたときの処理
calcButton.addEventListener("click", function () {
  // 入力値を数値に変換する
  const num1 = Number(num1Input.value);
  const num2 = Number(num2Input.value);

  // 足し算の結果を求める
  const total = add(num1, num2);

  // 結果を画面に表示する
  showResult(total);
});
JavaScript

このテンプレートは、今後のアプリ開発でも土台として使いやすい形です。

次の学習につながる考え方

ES Modulesを理解すると、この先で次のような発展がしやすくなります。

  • API通信の処理だけを別ファイルに分ける
  • バリデーション処理だけを別ファイルに分ける
  • 設定値や定数を別ファイルに分ける
  • 大きなアプリを役割ごとに整理する

つまり、Day 71は今後の実践的なJavaScript開発の土台です。初心者の方は、今は小さな例でもよいので、「役割で分ける感覚」をしっかり身につけることが大切です。

初心者が特に意識したい学び方

Day 71を学ぶときは、次の順番を意識すると理解が深まりやすいです。

  • まず1ファイル版のコードを理解する
  • そのコードの役割を分解する
  • 役割ごとに別ファイルへ移す
  • `export` と `import` でつなぐ
  • `type=”module”` を付けて動かす

初心者の方は、いきなり最初から全部分割されたコードを見るより、「元は1つだったものを分ける」流れで考えるとかなりわかりやすいです。

Day 71のゴールを整理する

Day 71では、次のことができるようになっていれば十分です。

  • ES Modulesが何をする仕組みか説明できる
  • `export` と `import` の役割を説明できる
  • 名前付きエクスポートの基本を書ける
  • 役割ごとにファイル分割できる
  • `script type=”module”` の必要性を理解できる
  • 相対パスで正しくファイルを読み込める

ここまでできれば、Day 71としてはとても順調です。第6フェーズの「実践的なJavaScript」へしっかり入れている状態です。

まとめ

Day 71では、第6フェーズ「実践的なJavaScript」の最初のテーマとして、ES Modulesを学びました。ES Modulesは、JavaScriptのコードを役割ごとにファイル分割し、export で外へ出し、import で別ファイルから読み込む仕組みです。これによって、コードの整理、再利用、修正のしやすさが大きく向上します。特に、計算処理、画面表示、全体の実行処理を分けるような構造は、初心者の方にとって非常に良い練習になります。

また、ブラウザでES Modulesを使うには script タグへ type="module" を付ける必要があること、import のパスは正確に書く必要があること、拡張子 .js を省略しないほうが安全であることなど、実践で重要な注意点も学びました。さらに、モジュール化はコードの読みやすさだけでなく、グローバル汚染を減らし、安全確認をしやすくする点でも価値があります。

次に進む前に、今回のテンプレートを実際に動かし、math.js に引き算や掛け算を追加したり、ui.js にエラーメッセージ表示関数を追加したりしてみるのがおすすめです。そして、「どのファイルが何の役割を持っていて、どの export をどこで import しているのか」を自分の言葉で説明できるようになると、Day 71の理解がかなり深まっています。

タイトルとURLをコピーしました