【JavaScript/TypeScript】Script / モジュール / CommonJS / ES Modules 完全入門

JavaScript / TypeScript

Script / モジュール / CommonJS / ES Modules って、どんなふうに違うのかな?

今回は JavaScript の Script / モジュール / CommonJS / ES Modules について取り上げてみたい思います。

Script とは?

Script とは従来の JavaScript の仕組みで、HTML 上で JavaScript を実行するために <script> タグを使って直接コードを書いたり、外部ファイルを読み込んだりする方法のこと です。

Script では、コードがグローバルスコープに置かれる ため、ファイル間の仕切りがなく、変数や関数の名前が衝突しやすいといった問題 があり、大きなアプリでは管理が難しくなってしまいます。

Script(従来のJavaScript)の特徴と問題点まとめ

特徴具体的な内容その結果起きる問題
グローバルスコープ変数や関数がすべて window に登録される変数名が衝突しやすい(上書き事故)
ファイル間の独立性がないどのファイルも同じ空間を共有他のファイルの影響を受けやすい
読み込み順に依存<script> の順番で実行される順番を間違えるとエラーになる
依存関係が明示できない「このファイルは何に依存しているか」書けないコードの見通しが悪い
再利用しにくい機能単位で分離しづらい大規模開発に不向き
strict modeが自動で有効にならない明示的に "use strict" が必要バグに気づきにくい

Script は、小規模なページでは問題ありませんが、機能が増えてファイル数が多くなったり、複数人で開発するようになると、同じ名前の変数がかぶってしまったり、どの順番で読み込めばよいのか分からなくなったりするといった問題 が起きやすくなります。

こうした問題を解決し、ファイルごとに役割を分けて、コードを整理しやすくするために生まれたのが、モジュール という仕組みです。

モジュール とは?

モジュール とは、プログラムを整理するため に、機能ごとに分けた部品(ファイル)のことです。

モジュールの目的

目的説明
整理する機能ごとにファイルを分けて読みやすくする
再利用する他のファイルから必要な機能だけを使えるようにする
衝突を防ぐファイルごとにスコープが分かれるため、同じ名前の変数があっても影響しない

スコープの例(ファイルごとに独立)

ファイルごとにスコープ(変数の範囲)が分かれている ため、同じ名前でも衝突しない

モジュールの使用例

ファイルごとにスコープ(変数の範囲)が分かれている ため、同じ名前でも衝突しない

モジュールのメリット

  • 機能ごとにファイルを分けて整理できる ことで、コードが読みやすくなる
  • ファイルごとにスコープ(適用範囲)が分割される ため、同じ名前の変数があっても衝突せずに安全に管理 できる
  • 他のファイルから必要な機能だけを外に出して (export) 使える (import)ようにでき、再利用しやすい
  • コードの整理・再利用・安全性の確保ができる

CommonJS とは?

CommonJS とは、Node.jsモジュールを扱うために作られた仕組みのこと で、React.js では直接使いませんが、サーバーサイドの JavaScript古いNode.jsパッケージ では、今でもよく見かけます。

背景

JavaScript はもともとブラウザの Script しかなく、ファイルを分けても ファイル同士の依存関係を管理することができません でした。
Node.js がサーバー上で JavaScript を使えるようになったとき、大規模な開発では どのファイルがどの機能を使うのかを整理する仕組み(モジュール) が必要になりました。
そこで作られたのが CommonJSです。

コード例

モジュールの作成(export)
モジュールの利用(import)

特徴

項目説明
書き方module.exports(出力する)
require() (読み込む)
読み込みタイミング実行時に読み込む(動的)
環境Node.js が中心(ブラウザでは直接使えない)
メリットサーバー上でファイルを分割・機能の再利用が可能
注意点静的解析ができないので、ツールによる最適化が難しい

ES Modules とは?

ES Modules とは、機能ごとに分けたファイル(モジュール)を、安全に分割・再利用できるようにした JavaScript の公式な仕組み です。

特徴として、ブラウザと Node.js の両方で使う ことができ、React.jsVue.js などの モダンなフロントエンド開発で標準的に使用 されています。

named export コード例

named export は、複数の機能をまとめてエクスポートする ときによく使用されます。
インポート時には { } が必要で、基本的には同じ名前を使用します
as を使用した場合、別名(alias)として名前の変更が可能

モジュールの作成(export)
モジュールの利用(import)

default エクスポート

export default は、1つのモジュールにつき1つだけエクスポートできインポート側では自由な名前を付けることができます。 ※ { } は不要 です。
default は、このモジュールの代表となる1つの機能をエクスポートする ときによく使われます。

モジュールの作成(export)
モジュールの利用(import)

特徴

特徴説明
書き方export / export default(出力する)
import(読み込む)
読み込みタイミング静的に読み込む(コンパイル時に依存関係が分かる)
環境ブラウザ + Node.js(モダン環境)
メリット・コードを整理・再利用しやすい
・静的解析が可能でツールによる最適化がしやすい
React.js やモダンフロントエンドの標準
注意点古い Node.js パッケージや古いブラウザでは使えない場合がある

CommonJS と ES Modules の違い

CommonJS ES Modules では、下記のような違いがあります

比較CommonJSES Modules
書き方require() / module.exportsimport / export
読み込み実行時(動的)静的(コンパイル時に依存関係が分かる)
環境Node.jsブラウザ + Node.js
React.jsVue.js での使用ほぼなし標準

React.js や Vue.js の場合

React.jsVue.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 を理解して効率的な開発を進めていきましょう。

tachu × tachu

Laravel / React フルスタックエンジニア

Webエンジニア歴15年、フリーランス歴8年で、PHP / Laravel を中心に、
React.js / Vue.js を用いたフルスタックでのWeb開発をしています。

技術記事は Laravel / React / Web開発 を中心に書いています。

Webサービスの開発、既存システム改善、機能追加、技術相談、小規模な開発など、お気軽にご相談ください。

JavaScript / TypeScript
シェアする

コメント

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