ReactなどモダンJSを学習中に「コンポーネントが取り込まれない」となったことがある初学者の方は多いと思います。
初学者向けの学習教材やスクールでは「JSファイルを複数に分けて管理する」と言うモジュールの扱い方をそこまで詳しく教えてくれません。
ですがモダンJSを筆頭にモジュールの考え方は駆け出しエンジニアでも必須の内容になっているため、本記事ではモジュールの基本について解説していきます。
また動画もあるので必要に応じて活用してください。
JavaScriptにおけるモジュールの作り方
モジュールとはJSファイルからJSファイルに値や関数をバケツリレーのように引き継ぐことを言います。
以下のようなHTMLとJSファイルがあったとします。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="./script.js" defer></script>
</head>
<body></body>
</html>
const num = 10;
console.log(num); // 「10」と出力される
index.htmlがscript.jsを読み込んでいるため「10」と言う出力ができました。
JSファイルについて以下のように別のファイルを用意します。
const hello = "hello";
module.jsと言うファイルの中にある定数helloをコンソールに表示するにはどうすれば良いでしょうか?
モジュールを作る基本のポイントは3点です。
まず引き継ぎたい内容にexportをつけます、これで別のJSファイルにデータを送ることができます。
// exportをつける
export const hello = "hello";
2点目は引き受けるJSファイルにimport文を書きます、import文によって事前にexportされたデータを「こちらのファイルで引き受けますよ」ということを示します。
// import文を書く
import { hello } from "./module.js";
const num = 10;
console.log(num);
import文の書き方は「import { データの名前 } from “データがあるJSファイルのパス”」となります。
JSファイルのパスは実行環境によって変わりますので必ずしも上記のコードと同じになるわけではありません。
最後にscript.jsを読み込んでいるHTMLファイルに専用の属性を追加します。
JSファイルを読み込むためのscriptタグの属性に「type=”module”」というものです。
これを追加することでモジュールを取り入れることができます。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<!-- scriptタグにtype="module"を追加 -->
<script src="./script.js" type="module" defer></script>
</head>
<body></body>
</html>
慣れないうちは難しく感じるかもしれませんが、以上の流れでモジュールを作ることができます。
ここまでの作業をやっていることでmodule.jsで作成した定数helloをscript.jsで使用できます。
// import文を書く
import { hello } from "./module.js";
const num = 10;
console.log(num); //「10」と出力される
console.log(hello); //「hello」と出力される
モジュールでは定数だけではなく様々なデータの種類を引き継ぐことができます。
export const hello = "hello";
export class Test {
constructor() {
console.log("Testクラスです");
}
}
export const array = [1, 2, 3, 4];
export function calc() {
let result = 1 + 2;
console.log(`calcの結果:${result}`);
}
import { hello, array, calc, Test } from "./module.js";
console.log("定数hello:", hello);
console.log("array:", array);
calc();
new Test();

同じファイルからimportする場合には{ }の中を「,」で区切ることで複数のexportに対応することができます。
importする時の名前を別のものに変えたいときは「新しい名前 * 元の名前」とすればOKです。
// 定数helloを「sayHello」という名前に変えて読み込む
import { sayHello as hello, array, calc, Test } from "./module.js";
console.log("定数hello:", sayHello);
console.log("array:", array);
calc();
new Test();
またexportする方法にも別の方法があるので紹介しておきます。
export const hello = "hello";
export class Test {
constructor() {
console.log("Testクラスです");
}
}
export const array = [1, 2, 3, 4];
export function calc() {
let result = 1 + 2;
console.log(`calcの結果:${result}`);
}
// ここから追加
function loop() {
for (let i = 0; i < 10; i++) {
console.log(i);
}
}
export default loop;
データの名前にexportする以外に、ファイルの最終行で「export default データ名」としてもデータを送ることができます。
ただこちらの方法でexportしたものはimport文の{ }の外でデータ名を書くルールになっています。
// export defaultしたものは{ } の外に名前を書くルール
import loop, { hello, array, calc, Test } from "./module.js";
console.log("定数hello:", hello);
new Test();
console.log("array:", array);
calc();
// ここを追加
loop();

exportの2種類についてはどちらも使用するので両方覚えておきましょう。
このようにモジュールの作り方を理解しておくとReactなどモダンJSに入った時もスムーズに理解していけることでしょう。