JavaScriptでimportを使わず依存関係のある複数ファイルを動的ロードする

2020/10/03

依存関係のある複数の JavaScript ファイルを動的に読み込みたいケースで、対応ブラウザの都合や export していない既存スクリプトを読み込みたいなどで import 構文を使えない状況に作業中に陥りました。単純に <script> 要素を動的に追加して読み込もうとすると、スクリプトのロードが非同期読み込みとなって、タイミング次第では依存関係のあるスクリプトの読み込み完了順が前後してしまい、エラーになります。

とりあえず、Element の onload イベントを使用して、スクリプトのロードが読み込み終わったら次のスクリプトをロードするような関数を作ったところ、うまく読み込めるようになりましたので、メモ代わりにその関数を貼っておきます。

この関数を使って読み込むと、スクリプトを配列のインデックス順で直列で読み込むようになるので依存があるスクリプトが正しい順序で読み込めるようになりますが、代わりにスクリプトの読み込み自体は遅くなります。依存関係のないファイルは並列で読むようにもう少し工夫の余地はありそうです。(そもそも無理やり複数ファイルを動的に読み込もうとしないで事前にオフラインで1ファイルに変換しておけよという...)

      
function createScriptElement(src, onloadFunc) {
    let element = document.createElement("script");
    element.type = "text/javascript";
    element.src = src;
    element.onload = onloadFunc;
    let headElement = document.getElementsByTagName('head')[0];
    headElement.appendChild(element);
}

function loadScripts(scriptFileNames, allScriptLoaded, index = 0) {
    if (index == scriptFileNames.length) {
        allScriptLoaded();
        return;
    }

    let jsRootPath = "./";
    let scriptFileName = scriptFileNames[index];
    let src = jsRootPath + scriptFileName;
    createScriptElement(src, x => {
        console.log(`loaded ${src}`);
        loadScripts(scriptFileNames, allScriptLoaded, ++index);
    });
}

loadScripts([
    "GlobalDefinitions.js",
    "Utilities.js",
    "Skill.js",
    "Tile.js",
    "Map.js",
    "Structures.js",
    "Table.js",
    "Unit.js",
    "DamageCalculator.js",
    "TurnSetting.js",
    "AudioManager.js",
    "AetherRaidDefensePresets.js",
    "AppData.js",
    "SettingManager.js",
    "Main_ImageProcessing.js",
    "Main.js",
], () => { console.log("loaded all"); });

      
      


  このエントリーをはてなブックマークに追加    

<<「Web 開発」の記事一覧に戻る

関連記事