JavaScriptにおけるモジュール

JavaScriptにおけるモジュール

この記事ではJavaScriptにおけるモジュールについて説明します。

YouTube Video

JavaScriptにおけるモジュール

JavaScriptにおけるモジュールは、コードを整理し再利用可能なコンポーネントに分割するための仕組みです。モジュールを使用することで、コードの可読性や保守性が向上し、他のプロジェクトでも同じ機能を使い回すことができます。ここでは、モジュールの概念から具体的な使い方まで、さまざまなモジュールシステムについて解説します。

JavaScriptモジュールの概念

JavaScriptは、もともとモジュール化された仕組みを持っていませんでした。しかし、アプリケーションが大規模化するにつれ、コードを小さな単位に分け、再利用できるようにするためのモジュール化が重要視されるようになりました。モジュールは、特定の機能を持つコードの塊であり、他のコードと独立して扱えるため、複数のファイルに分割して管理することができます。

モジュールの主な種類

JavaScriptにはいくつかのモジュールシステムがあります。最も一般的なものは、ES Modules(ESM)とCommonJSです。

  • ES Modulesは、ECMAScript 2015(ES6)で導入されたモジュールシステムで、importexportというキーワードを使ってモジュールを定義します。このシステムは、クライアントサイド(ブラウザ)やサーバーサイド(Node.js)で広く利用されています。

  • CommonJSは、主にNode.jsで使用されるモジュールシステムです。requiremodule.exportsを使ってモジュールを定義し、ファイルをインポート・エクスポートします。

ES Modules(ESM)の詳細

ES Modulesは、JavaScriptの標準的なモジュールシステムで、モジュール間で機能を簡単にやり取りできます。ブラウザやNode.jsでは、このシステムを用いてモジュールを定義し、インポートします。

exportimport

exportはモジュールから外部に機能を公開するためのキーワードです。importは他のモジュールで定義された機能を取り込むために使います。

例: モジュールのエクスポート

ES Modulesでのモジュールのエクスポートは次のように行えます。

1// math.mjs
2export function add(a, b) {
3    return a + b;
4}
5export function subtract(a, b) {
6    return a - b;
7}

このmath.mjsモジュールでは、addsubtractという関数をエクスポートしています。他のモジュールからこの関数をインポートすることが可能です。

ここで、.mjsES Modules形式のJavaScriptファイルであることを明示する拡張子です。Node.jsでは、ファイル拡張子によってCommonJSES Modulesかを判断します。ただし、package.jsontype: "module"を指定すると、デフォルトで.js拡張子がES Modulesとして扱われます。

例: モジュールのインポート

ES Modulesでのモジュールのインポートは次のように行えます。

1// main.mjs
2import { add, subtract } from './math.mjs';
3
4console.log(add(3, 5)); // 8
5console.log(subtract(10, 7)); // 3

このように、importを使うことで、別のファイルで定義された関数を簡単に利用できます。

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

モジュールには、2つのエクスポート方法があります。1つは名前付きエクスポート、もう1つはデフォルトエクスポートです。

  • 名前付きエクスポートは、モジュールから複数の関数や変数をエクスポートする際に使用します。複数のエクスポートを行うことができ、インポートする際には指定した名前で受け取ります。
1// utils.mjs
2export function sum(a, b) {
3    return a + b;
4}
5export function multiply(a, b) {
6    return a * b;
7}
1// main.mjs
2import { sum, multiply } from './utils.mjs';
3
4console.log(sum(4, 6));       // 10
5console.log(multiply(3, 5));  // 15
  • デフォルトエクスポートは、モジュールから1つの関数やクラスをエクスポートする際に使用します。インポート時には、任意の名前で受け取ることが可能です。
1// greet.mjs
2export default function greet() {
3    return "Hello, World!";
4}
1// main.mjs
2import greet from './greet.mjs';
3
4console.log(greet()); // "Hello, World!"

デフォルトエクスポートは1つしかエクスポートできませんが、名前付きエクスポートは複数の要素を同時にエクスポートできます。

クライアントサイド(ブラウザ)での利用例

例: モジュールのエクスポート

ES Modulesでのモジュールのエクスポートは次のように行えます。

1// utils.js
2export function sum(a, b) {
3    return a + b;
4}
5export function multiply(a, b) {
6    return a * b;
7}

このutils.jsモジュールでは、summultiplyという関数をエクスポートしています。

例: モジュールのインポート

クライアントサイドでのモジュールのインポートは次のように行えます。

 1<!DOCTYPE html>
 2<html lang="ja">
 3<head>
 4  <meta charset="UTF-8">
 5  <title>ES Modules Sample in HTML</title>
 6</head>
 7<body>
 8  <h1>ES Modules Sample</h1>
 9  <div id="result"></div>
10
11  <script type="module">
12    import { sum, multiply } from './utils.js';
13
14    const result = `
15      <p>sum(3, 5) = ${sum(3, 5)}</p>
16      <p>multiply(10, 7) = ${multiply(10, 7)}</p>
17    `;
18
19    document.getElementById('result').innerHTML = result;
20    console.log(sum(3, 5));      // 8
21    console.log(multiply(10, 7)); // 70
22  </script>
23</body>
24</html>
  • <script>タグのtype属性にmoduleを指定することで、importexportなどのHTML内でもESモジュール構文が利用可能です。
  • import文で外部のutils.jsを読み込み、結果を表示します。

CommonJSの詳細

CommonJSは、主にNode.jsで使用されるモジュールシステムです。module.exportsrequireを使ってモジュールをエクスポートおよびインポートします。

requiremodule.exports

CommonJSでは、モジュールをエクスポートするためにmodule.exportsを使います。また、モジュールを他のファイルから利用するためにはrequireを使います。

例: モジュールのエクスポート

CommonJSでのモジュールのエクスポートは次のように行えます。

1// math.js
2module.exports = {
3    add: function(a, b) {
4        return a + b;
5    },
6    subtract: function(a, b) {
7        return a - b;
8    }
9};
例: モジュールのインポート

CommonJSでのモジュールのインポートは次のように行えます。

1// main.js
2const math = require('./math.js');
3
4console.log(math.add(4, 7));      // 11
5console.log(math.subtract(9, 2)); // 7

Node.jsではCommonJSがデフォルトのモジュールシステムとして使用されていますが、ES Modulesもサポートされています。

動的インポート

JavaScriptでは、import()を使ってモジュールを動的にインポートすることができます。この手法は非同期処理を利用して、必要なときにモジュールをロードする仕組みです。

動的インポートは次のように行えます。

1async function loadModule() {
2    const math = await import('./math.js');
3    console.log(math.add(5, 3)); // 8
4}
5
6loadModule();

動的インポートは、アプリケーションのパフォーマンスを向上させる手段の一つです。初期ロード時にすべてのモジュールを読み込むのではなく、必要に応じてモジュールをロードできるため、ページの表示速度が向上します。

モジュールの利点

  • コードの再利用

    • モジュール化されたコードは、別のプロジェクトでも使い回しが可能です。 共通の機能を持つモジュールを作成し、複数のアプリケーションで利用することで、開発効率が大幅に向上します。
  • 保守性の向上

    • コードをモジュールごとに分割することで、特定の機能や部分だけを簡単に修正できます。 小さな単位でコードを管理することにより、バグの発見や修正が容易になります。
  • 名前空間の衝突回避

    • グローバルスコープに多くの変数や関数を定義すると、名前の衝突が発生する可能性がありますが、モジュール化することでそれを防ぎ、よりクリーンなコードベースを保つことができます。
  • 依存関係の管理

    • モジュールを使うことで、アプリケーションの依存関係を明示的に管理できます。 どのモジュールが他のモジュールに依存しているのかが明確になるため、コードの構造が理解しやすくなります。

まとめ

JavaScriptのモジュールシステムは、コードを整理し、再利用可能なコンポーネントに分割するための強力な手段です。ES ModulesとCommonJSの違いを理解し、プロジェクトに応じて適切なモジュールシステムを選ぶことで、コードの可読性と保守性を高めることができます。また、動的インポートを利用すれば、アプリケーションのパフォーマンスも最適化できます。

モジュールシステムを活用し、よりスケーラブルで効率的なJavaScriptアプリケーションを構築していきましょう。

YouTubeチャンネルでは、Visual Studio Codeを用いて上記の記事を見ながら確認できます。 ぜひYouTubeチャンネルもご覧ください。

YouTube Video