JavaScriptの新しい仕様には、モジュールという仕組みがあります。現時点では一部のブラウザしか対応していませんが、ECMAScript 2015のModulesの標準仕様として策定されているため、やがて全てのブラウザで使えるようになっていくでしょう。この機能は、ES2015 Modules、ES6 Modules、ES Modules、ESMなどと呼ばれています(以下、ES Modulesと記載します)。
webpack 2+やRollup.jsなどのモダンなフロントエンドのツールを通して、すでにES Modulesを使っているエンジニアも多いと思います。この記事では、ブラウザネイティブで使えるES Modulesに焦点をあて、ES Modulesの導入で解決できる課題と利点を紹介します。
HTML+JSではモジュールの仕組みがなかった
JavaScript自体には他のJSファイルを取り込む標準的な仕様がいままではありませんでした。従来だと、外部JS(例えばjQueryのライブラリなど)を読み込みたい時に、HTMLファイルにscript
タグを書き込むことで別ファイルを読み込んでいました。例えば次のようなコードです。
< script src = "js/vender/jquery.min.js" ></ script > |
< script src = "js/vender/jquery.cookie.js" ></ script > |
< script src = "js/vender/jquery.easing.1.3.js" ></ script > |
< script src = "js/common.js" ></ script > |
< script src = "js/utils.js" ></ script > |
< script src = "js/app.js" ></ script > |
この方法だと扱いづらい点があります。
- HTMLファイルと密結合となる
- JSファイル単独で管理できない
- 読み込みの順番を気にしなければならない
これを解決するための手段として、様々なアプローチが登場しました。有名なところだと、AMD(+RequireJS)やCommonJS(+Browserify)などの技術があります。これらは独自仕様だったため、これからはES Modulesが標準仕様として取って代わっていくと考えられます。
サンプルで理解するES Modules
ES Modulesをブラウザで使うにはいくつか手順があります。サンプルを通して、一つ一つ抑えていきましょう。
利用可能なブラウザ
まずは利用できるブラウザを用意ください。デフォルトでES Modulesを使えるのは次のブラウザです。ES Modulesの搭載はSafariが先行していました。
- iOS Safari 10.1以上 (2017年3月リリース)
- macOS Safari 10.3以上 (2017年3月リリース)
- Chrome 61以上 (2017年8月リリース)
▼ES Modulesのブラウザサポート状況。「Can I Use…」より

EdgeやFirefoxはフラグ設定でES Modulesを利用できるため、将来的にフラグ設定無しで搭載されるかもしれません。
読み込まれる側の処理
まずはモジュールとしての外部JSファイルを用意しましょう。次のコードはブラウザでアラートを表示するだけのサンプルコードです。
▼sample-alert.js
export function sayMessage(message) { |
外部ファイルのJSファイルではexport
文を使って定義します。export
で宣言されたものだけが他のJSファイルから参照できます。
読み込む側の処理
HTMLには次のコードを記述します。従来はtype="text/javascript"
と記載していましたが、ES Modulesを使う時はtype="module"
と書きます。module
を指定しないと、import
やexport
などのJSコード内の宣言がエラーとなります。
▼パターン1
import {sayMessage} from "./sample-alert.js"; |
src
属性で外部ファイルを指定できます。インラインでも外部ファイルでも、どちらでもES Modulesを読み込めます。
▼パターン2
< script type = "module" src = "index.js" ></ script > |
import {sayMessage} from "./sample-alert.js" ; |
import
文のfrom
の中では必ず./
や../
、/
、といったパスで記述しなければなりません。xxx.js
というように記述するのはNGで、./xxx.js
とファイルパスを明確に記載します。拡張子も必須です。Node.jsでは拡張子無しの記述ができましたが、ブラウザでは必ず拡張子を記載ください。
これをブラウザで開くとJSファイルで記載されたコードが実行されていることがわかります。

外部JSも扱える
もう一つ興味深いサンプルを紹介しましょう。import
文にはURLも指定できます。ES Modulesに対応した外部JSであれば、CDNから読み込めるので次のように記載できます。
import * as THREE from 'https://cdnjs.cloudflare.com/ajax/libs/three.js/87/three.module.js'; |
次の作例はWebGL用のJSライブラリThree.jsを使ったサンプルです。

注意点として、どのJSライブラリでもES Modulesとして読み込めるわけではありません。Three.jsはES Modulesで設計された数少ないJSライブラリです。有名どころだとjQueryやReact、Vue.jsなどはES Modulesとして配布されていないため、現時点ではブラウザネイティブではES Modulesとして利用できません。
次のページではES Modulesの課題や、モジュールバンドラーとの棲み分けについて紹介します。