JavaScriptにおけるdynamic import(動的import)の使い方
JavaScriptにおけるdynamic import(動的import)の使い方
一部の機能をページのロード時には読み込まず、何らかのイベント発火時にはじめて読み込むようにして初期リクエスト量を抑える。<button>クリックで読み込んで実行する想定の場合。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="icon" type="image/x-icon" href="***"> <script defer src="main.js"></script> <title>Page Title</title> </head> <body> <button>test</button> </body> </html> |
TypeScriptでdynamic importを使いたいときはtsconfig.jsonのmoduleはes2022以上を指定する必要がある。
モジュール側(イベント後に読み込まれる機能)
1 2 3 4 5 6 |
// sub.ts function subMethod(): void { console.log(`subMethod 実行`); } export { subMethod }; |
本体側(ページロード時に読み込まれる本体)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// main.ts // 非同期の関数としてモジュールを受け取っておく async function Dofunc(): Promise<void> { const module = await import('./sub'); // async/awaitをつけることででPromiseが返る // 実行内容 module.subMethod(); } // ボタンクリック時にモジュールを読み込んで実行 const btn: HTMLButtonElement | null = document.querySelector('button'); if (btn !== null) { btn.addEventListener('click',(): void => { void Dofunc(); },{ passive: true }); } |
本体側(async/awaitを使わないで非同期通信を使う方法)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
function Dofunc(): void { import('./sub') // import関数はasync/awaitが無くてもPromiseが返る。その後は従来のthen(), catch()で処理。 .then((module): void => { module.subMethod(); }) .catch((e: unknown): void => { if (e instanceof Error) console.log(e.message); }); } // ボタンクリック時にモジュールを読み込んで実行 const btn: HTMLButtonElement | null = document.querySelector('button'); if (btn !== null) { btn.addEventListener('click',(): void => { void Dofunc(); },{ passive: true }); } |
本体側(async/awaitを使いつつもエラーハンドリングもする場合)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
async function Dofunc(): Promise<void> { try { const module = await import('./sub'); // 実行内容 module.subMethod(); throw new Error(`'sub.ts' doesn't exist`); } catch (e) { if (e instanceof Error) console.log(e.message); } } // ボタンクリック時にモジュールを読み込んで実行 const btn: HTMLButtonElement | null = document.querySelector('button'); if (btn !== null) { btn.addEventListener('click',(): void => { void Dofunc(); },{ passive: true }); } |
モジュール側でexport default subMethod;(default export)した場合は、本体側での実行関数名はmodule.default();
わざと時間差をつくりイベント発火後に読み込まれることを確認する例
本体側
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
function Dofunc(): void { setTimeout((): void => { import('./sub') // import関数はasync/awaitが無くてもPromiseが返る。その後は従来のthen(), catch()で処理。 .then((module): void => { module.subMethod(); }) .catch((e: unknown): void => { if (e instanceof Error) console.log(e.message); }); }, 3000); } const btn: HTMLButtonElement | null = document.querySelector('button'); if (btn !== null) { btn.addEventListener('click',(): void => { void Dofunc(); },{ passive: true }); } |
コメント
コメントはありません。