別のJavaScriptのファイルを動的に読み込む - JavaSctiptコードを別のファイルに分割する

別のJavaScriptのファイルを動的に読み込むコードを紹介します。

概要

こちらの記事では複数のJavaScriptファイルに分割されたコードを読み込む方法を紹介しました。
この方法で処理は実行できますが、HTMLファイル側にアクセスするすべてのJavaScriptファイルのlinkタグを記述する必要があり、コードもきれいでなく、モジュール化のメリットも薄れてしまいます。 そのため、最近のWebブラウザでは、動的にJavaScriptの別のファイルを読み込んで参照できる機能が追加されています。この記事では、動的に別のJavaScriptファイルを読み込み参照先のJavaScriptのコードを実行する例を紹介します。

方法

JavaScriptのimport 文を利用すると動的にJavaScriptファイルを読み込めます。
注意
Internet Explorer では動作しないため注意が必要です。

書式

非同期に実行する場合

import('インポートするJavaSciptファイル').then({ 読み込みモジュール変数 => {
});

同期して実行する場合

読み込みモジュール変数 = await import('インポートするJavaSciptファイル')
同期処理の場合は関数を非同期関数にする必要があります。

例1 : 非同期でクラスを読み込む

コード

下記の3ファイルを作成します。
index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
  <script src="app.js"></script>
</head>
<body>
  <div>
    <a href="javascript:onclick();">実行</a><br />
  </div>
  <div id="output"></div>
</body>
</html>
app.js
function onclick() {
  import('./mylib.js').then(module => {
    var m = new module.myutil();
    var elem = document.getElementById("output");
    var ret = m.proc(2, 8);
    elem.innerText = ret;
  });
}
mylib.js
export class myutil {
  proc(val1, val2) {
    var result1 = val1 + val2;
    return result1;
   }
}

解説

mylib.jsがライブラリ部分になります。このファイルにmyutilクラスを実装しています。クラス内にはprocメソッドがあり2つの引数の和を返すメソッドです。
app.jsがアプリケーションの処理を記述するJavaScriptファイルです。onclick() 関数が呼び出されると、下記のコードでmylib.jsを動的に読み込みます。import文は非同期のため、処理が完了したタイミングでthenメソッド内が実行されます。
thenメソッド内には引数を1つ受け取るコードバック関数を与えます。今回はmoduleという名称の引数にしています。thenメソッド内が実行される際に、module変数に読み込んだモジュールのオブジェクトが与えられます。
import('./mylib.js').then(module => {
});

new文でモジュール内の myutil クラスをインスタンス化します。
  var m = new module.myutil();

インスタンス化された後は、通常のクラスと同じ記述で利用できます。output IDを持つ要素を取得し、myutilクラスのprocメソッドを呼び出し、結果をoutput IDを持つ要素内に表示します。
  var elem = document.getElementById("output");
  var ret = m.proc(2, 8);
  elem.innerText = ret;

実行結果

HTMLファイルをWebブラウザで表示します。下図の画面が表示されます。[実行]のリンクをクリックします。


リンクの下に結果が表示されます。myutilクラスのprocメソッドが呼び出されて2つの引数の和が画面に表示されることが確認できます。

例2 : 同期処理でクラスを読み込む

コード

下記の3ファイルを作成します。
index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
  <script src="app.js"></script>
</head>
<body>
  <div>
    <a href="javascript:onclick_await();">実行 (await)</a><br />
  </div>

  <div id="output"></div>

</body>
</html>
app.js
async function onclick_await() {
  const module = await import('./mylib.js');
  const m = new module.myutil();
  var elem = document.getElementById("output");
  var ret = m.proc(2, 8);
  elem.innerText = ret;
}
mylib.js
export class myutil {
  proc(val1, val2) {
    var result1 = val1 + val2;
    return result1;
   }
}

解説

mylib.jsがライブラリ部分になります。このファイルにmyutilクラスを実装しています。コードは先の非同期実行のコードと同じです。クラス内にはprocメソッドがあり2つの引数の和を返すメソッドです。
app.jsがアプリケーションの処理を記述するJavaScriptファイルです。onclick_await() 関数が呼び出されると、下記のコードでmylib.jsを動的に読み込みます。import文は非同期実行されますが、await句を記述すると処理の完了までこの行で待つことができます。処理が完了したタイミングで次の行以降が実行されます。import文の戻り値として読み込んだモジュールのオブジェクトが返ります。
  const module = await import('./mylib.js');

new文でモジュール内の myutil クラスをインスタンス化します。
  const m = new module.myutil();

インスタンス化された後は、通常のクラスと同じ記述で利用できます。output IDを持つ要素を取得し、myutilクラスのprocメソッドを呼び出し、結果をoutput IDを持つ要素内に表示します。
  var elem = document.getElementById("output");
  var ret = m.proc(2, 8);
  elem.innerText = ret;

実行結果

HTMLファイルをWebブラウザで表示します。下図の画面が表示されます。[実行 (await)]のリンクをクリックします。


リンクの下に結果が表示されます。myutilクラスのprocメソッドが呼び出されて2つの引数の和が画面に表示されることが確認できます。

例3 : 非同期で関数を読み込む

先の例はimport文を利用してクラスを読み込みましたが、クラスでない単体の関数をimport文で参照することもできます。

コード

index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
  <script src="app.js"></script>
</head>
<body>
  <div>
    <a href="javascript:onclick();">実行</a><br />
  </div>
  <div id="output"></div>
</body>
</html>
app.js
function onclick() {
  import('./mylib.js').then(func => {
    var elem = document.getElementById("output");
    var ret = func.proc(4, 2);
    elem.innerText = ret;
  });
}
mylib.js
export function proc(val1, val2) {
  var result1 = val1 + val2;
  return result1;
}

解説

mylib.jsがライブラリ部分になります。このファイルにproc関数を実装しています。proc関数は2つの引数の和を返します。
app.jsがアプリケーションの処理を記述するJavaScriptファイルです。onclick() 関数が呼び出されると、import文を利用してmylib.jsを動的に読み込みます。。import文は非同期のため、処理が完了したタイミングでthenメソッド内が実行されます。
thenメソッド内には引数を1つ受け取るコードバック関数を与えます。今回はfuncという名称の引数にしています。thenメソッド内が実行される際に、func変数に読み込んだモジュールのオブジェクトが与えられます。
import('./mylib.js').then(func => {
});

関数の呼び出しはモジュールオブジェクト.関数名 の記述で利用できます。output IDを持つ要素を取得し、読み込んだモジュールのprocメソッドを呼び出し、結果をoutput IDを持つ要素内に表示します。
    var elem = document.getElementById("output");
    var ret = func.proc(4, 2);
    elem.innerText = ret;

実行結果

上記のHTMLファイルをWebブラウザで表示します。下図のページが表示されます。[実行]リンクをクリックします。


リンクの下に結果が表示されます。app.jsの処理が実行され、mylib.jsのproc関数が参照され処理ができていることが確認できます。

例4 : 同期処理で関数を読み込む

先のimport文を利用して関数を読み込む処理を同期処理で実行する例です。

コード

index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
  <script src="app.js"></script>
</head>
<body>
  <div>
    <a href="javascript:onclick_await();">実行 (await)</a><br />
  </div>
  <div id="output"></div>
</body>
</html>
app.js
async function onclick_await() {
  const func = await import('./mylib.js');
  var elem = document.getElementById("output");
  var ret = func.proc(4, 2);
  elem.innerText = ret;
}
mylib.js
export function proc(val1, val2) {
  var result1 = val1 + val2;
  return result1;
}

解説

mylib.jsがライブラリ部分になります。このファイルにproc関数を実装しています。コードは先の非同期実行のコードと同じです。proc関数は2つの引数の和を返します。
app.jsがアプリケーションの処理を記述するJavaScriptファイルです。onclick_await() 関数が呼び出されると、下記のコードでmylib.jsを動的に読み込みます。import文は非同期実行されますが、await句を記述すると処理の完了までこの行で待つことができます。処理が完了したタイミングで次の行以降が実行されます。import文の戻り値として読み込んだモジュールのオブジェクトが返ります。
  const func = await import('./mylib.js');

関数の呼び出しはモジュールオブジェクト.関数名 の記述で利用できます。output IDを持つ要素を取得し、読み込んだモジュールのprocメソッドを呼び出し、結果をoutput IDを持つ要素内に表示します。
  var elem = document.getElementById("output");
  var ret = func.proc(4, 2);
  elem.innerText = ret;

実行結果

上記のHTMLファイルをWebブラウザで表示します。下図のページが表示されます。[実行 (await)] リンクをクリックします。


リンクの下に結果が表示されます。app.jsから mylib.jsが参照され、参照先のproc関数が呼び出されて処理が実行できていることが確認できます。


このページのキーワード
  • 別のJSのファイルを動的に読み込む - JavaSctiptコードを別のファイルに分割する
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
掲載日: 2020-03-15
iPentec all rights reserverd.