はじめに
JavaScript界隈でよく登場するモジュールとかバンドルとかって結局何だっけ?何で必要なの?となり、都度ググるのが面倒なので、自分なりに各用語を簡単にまとめてみました。
難しい細部までは追わずに、各用語を順追って、大枠だけつらつらと書いていきます。
対象読者
- モジュールとかバンドルとかwebpackとかって言われてもピンと来ない人
※ 初学者向けです
モジュールとは?
機能ごとに分割されたファイルのこと。
変数や関数が書かれたプログラムのことで、基本的には1ファイルのことをモジュールと呼ぶという認識で基本はOKです。
ちなみに、元々JavaScriptは、Webページでちょっとした機能を提供する用途で開発された言語だったので、このモジュールを定義したり、読み込んだりという機能が言語仕様として用意されていなかったという背景があります。
なので、JavaScriptでもモジュール化したいよね〜ということで後述の話に繋がっていきます。
なお、他のプログラミング言語では、このモジュールを使うための機能が、標準で用意されていることが多いらしいです(特段意識せず、import/exportできるのがそれです)
モジュール化するメリットって何?
各モジュール単位でプログラムを管理出来るので保守性や可読性、再利用性が高くなります。
モジュール化されていないクソデカファイルは、保守性や可読性が悪いですし、モジュール化することによって、保守性や可読性の向上+とあるモジュールを使い回すといったようなことができるので、再利用性も向上します。
変数名や関数名の意図しない衝突なども避ける意味で、名前空間的にもメリットがあります。
モジュール化ってどうやるの?
言語としてモジュール化の機能が用意されていないJavaScriptでモジュール化ってどうやるの?やりたいよね?ということでまず誕生したのが、CommonJSです。
1. CommonJS(require構文)
Webブラウザ外のJavaScriptのモジュールシステムの仕様を定めるプロジェクトである「CommonJS」で策定されたモジュール機能というか仕様になります。
構文としては以下のような感じです。今でもたまに見かけると思います。
// モジュールをエクスポート
module.exports = { hoge }
// モジュールをインポート
const hoge = require('hoge')
ただ、このCommonJSのモジュール動作仕様は、あくまでブラウザ外(≒ サーバーサイド)向けに設計された機能であり、ブラウザではサポートされていないため、ブラウザで動かす場合は、後述するwebpackなどで依存関係を解決してあげる(モジュールをバンドルする)必要があります。
2. ESmodules(import/export構文)
ES2015(ES6)で導入された待望のJavaScript言語標準のモジュール機能がESmodulesです。JSのモジュールシステムとしては後発になります。
構文としては以下のような感じで、今では1番見かける書き方かなと思います。
// モジュールをエクスポート
export const hoge = "hoge"
// モジュールをインポート
import { hoge } from 'path/to/file'
現行の多くのブラウザでは、ESModulesを標準でサポートしているようです。
バンドルとは?
上記で説明したモジュール化されたファイル群を1つのJSファイルにまとめることを指します。
読み込むJSファイルが多いということは、そのファイルの分だけブラウザからJSファイルへのHTTPリクエストの数も増えてしまいます(そういう仕様)
一方、1つのファイルにまとまっていると、そのファイルを読み込むだけで良くなります。
この辺りを理解していると、バンドル(というかバンドラー)の存在意義がより理解しやすくなると思います。
webpackとは?
モジュールバンドラーの1つです。最近ではViteやesbuildなどの高速なモジュールバンドラーが利用されることが増えてきております。
webpack(Vite, esbuild)等のバンドラーの必要性とは?
ツール(ライブラリ)によって機能差はあると思いますが、バンドラーというものはモジュールバンドル以外にも、色々なことをやってくれることが多いです。
例えば、ミニファイ(コードペース削除や変数名短縮等を行う)やツリーシェイク(未使用コード削除)等のコードの最適化も行ったりしています。
トランスパイルとは?
(JSにおける)トランスパイルとは、JSで書かれたソースコードを、別のバージョンのコードに変換することを言います。
例えば、ES2015に対応していないような古いブラウザで、ES2015以降の構文で記述されたJavaScriptを動かすためにトランスパイルをする必要があります。
かつてはBabelというライブラリがよく使われていましたが、現在はesbuildなどのバンドラーがトランスパイルも行うことが多いようです。
終わりに
簡単にですが、まとめてみました。
近年では、ブラウザ(JSエンジン)の高速化やWeb APIの進化を背景に、ブラウザでできることが増えて、Webページ・アプリケーションで求められる要件(パフォーマンスやアクセシビリティ等)が高度化し、ReactなどのJSフレームワーク(ライブラリ)が数多く登場といった中で、ブラウザだけでなくサーバーサイドにおいてもJavaScriptやTypeScriptの存在感が増している印象です。
結局フレームワークやツールはこの辺りのコア部分の面倒なことを抽象化してくれているだけなので、フレームワークに依存しすぎるフレームワーカーにはならず、きちんと地に足つけてコア部分の知識を日々深めていくことが良いのかなと思います。