かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

HTMLでES moduleをつかうメモ

ES2015で、scriptタグモのtyoeで指定できるモードにmoduleが追加されたようです。

  • script:グローバル名前空間を必要とする標準的なスクリプトのためのもの
  • module:明示的なインポートとエクスポートを必要とする、モジュール化されたコードのためのもの

scriptモードでimport文またはexport文を使おうとすると、SyntaxErrorが起こります。これらの文は、グローバルなコンテキストでは無意味です。一方で、moduleモードはstrictモードを必ず必要とし、このモードではwith文などの言語機能が禁じられます。よって、モードの定義は、スクリプト構文解析と実行の前に、行う必要があります。

HTMLでES moduleを使う

<script type="module">で読み込ませたJavaScriptファイルでは import/export が使えます。
また、HTML上でscript type="module"を使ってES moduleを使う時は、nodeで使うときと異なり拡張子は.jsのままでOK。

2018.12.15時点での対応ブラウザ: ES6 module | Can I use
f:id:kikiki-kiki:20181215151920p:plain

/src/math-module.js

export function square(x) {
  return x * x;
}
export function cube(x) {
  return x * x * x;
}

/src/main.js

import {square, cube} from './math-module.js';

function component() {
  const element = document.createElement('pre');
  element.innerHTML = [
    'Hello ES module! script type="module"',
    `5 cubed is equal to ${cube(5)}`
  ].join('\n\n');

  return element;
}

document.body.appendChild(component());

HTML

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>ES Module TEST</title>
  <script type="module" src="src/main.js"></script>
</head>
<body>
</body>
</html>

main.jsからimportしているJSファイルが読み込まれ、exportしている関数が使用できています。
f:id:kikiki-kiki:20181215153830p:plain

script type="module"で importする時に気をつけること

importするファイルのパスは絶対パスまたは、/./../から始まってないと読み込まれません。
また、import "lodash"のような拡張子が無い場合も正しく読み込まれません。(Chrome70では拡張子のないファイルを読み込もうとしていました)

まとめ

HTML上で<script type="module">を使ってモジュールとしてスクリプトを読み込ませることが出来ました。
単純にHTMLを作成してモジュール化したJSのアプリが試せるので良いかもしれません。
ただ、importごとにリクエストが発生してJSファイルを読み込むようなので、書捨ての実験でないようなプロダクトではwebpackなどで1つのファイルにまとめたものを使うのが良さそうだなと思いました。


[参考]

モジュール化の終焉―統合への回帰

モジュール化の終焉―統合への回帰