0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

クラスファイルのダイナミックimportは

Last updated at Posted at 2025-01-14

はじめに

ダイナミックimportのメリットを確かめているところです。
クラスファイルをダイナミックimportしようとサンプルを作成して確かめています。一つのクラスファイルに複数のクラスを定義して、それぞれにexportするクラスとexportしないクラスを作り、ダイナミックimportでクラスのロード状況をチェックしました。すると、exportするしないにかかわらず、すべてのクラスがロードされていました。
当初思っていたことと違っていました。てっきり、exportしないクラスはロードされないものと思っていました。
このように、ダイナミックimportと言っても、仕様を思い違いしているケースは多いと思います。
ダイナミックimportのうたい文句は、必要のあるモジュールのみをロードするとありますので、そうなると思っていました。

デバッグしているページ(サンプル)

main

ではどうすればいいのか

一つのクラスファイルに何でもかんでも入れるのではなく、機能を分けてそれぞれのクラスファイルにすれば、選択的ダイナミックimportができるようになります。
その場合は、import("クラスAフィル");import("クラスBフィル");import("クラスXフィル");というようにすればいいはずです。
必要なクラスファイルだけ、ダイナミックimport()します。

exportしていないクラスファイルをダイナミックimportするとエラーになります。

aaa.js
//
export class AAA{
    
    aaa(){
        alert("メソッドaaa()コール。");
    }
    bbb(){
        alert("メソッドbbb()コール。");
    }
}
//
class BBB{
    
    aaa(){
        alert("メソッドaaa()コール。");
    }
    bbb(){
        alert("メソッドbbb()コール。");
    }
}
main.js
//
import("./aaa.js");

よくあるエラーは

'undefined'エラーはよく発生しますが、これが中々、くせものです。
あるオブジェクトのプロパティを参照するところで、そのオブジェクト自体がまだ、未設定のまま、そこのあるプロパティを参照しようとしているケースです。これが、中々、気づきません。
デバック中に、結構、不用意に、オブジェクトの設定個所を移動していたりしています。その時に、プロパティの参照個所までは変更しないまま、テストを続けているとundefinedエラーが発生してしまいます。迂闊と言えば迂闊です。その時、すぐに気が付けばいいのですが、これが、デバッグを焦っていると中々、気づけません。
早く改修しなければというプレッシャーがより、解決を遅らせています。

こういう時こそ、落ち着いて、原因の解明に努めなければいけません。これは、知識があるないには関係ありません。

よくある不具合の現象は

これもデバックをしているとよく、出会います。それは、ページを新たにタブに初期状態で表示させたときです。必要な要素が表示されていないのです。仕方がなく、リロードしてみます。すると表示されます。このように、何回かリロードしてみると表示されますが、初回は表示されないという現象です。
これも、突き詰めて調べて行くと、その時点で必要なオブジェクトがundefinedになっていたということがわかります。
原因はわかりましたが、それでは、どこで、どのタイミングで、そのオブジェクトにデータを設定したらいいのかを見極めることが簡単ではありません。
その実行タイミング、場所を見つけるのが結構、難しいです。
ダイナミックimportを使用していると、これが関係してきます。
これのヒットのサンプルコードを以下に示します。
修正前

main.js
/*****************************************************************
 *初期化
 *ページをロード後にコール
 *  
 ******************************************************************/
window.addEventListener('load', function () {
        //ここで、auto_start()を実行するには、条件があり、必ず、先にglistobjが生成されていなければならない。さもないとundefinedエラーになる。        
        auto_start("8ODcuS8bUuc");  //河内おとこ節

});

これは、不用意にも、glistobjオブジェクトを初期化していない状態で、それを使用している、auto_start(....)をコールしていました。

修正後
以下は、@junerさんのコメントを採用させていただきました。

mai.js
const moduleWait = import('./favoriteClass.js');
/*****************************************************************
 *初期化
 *ページをロード後にコール
 *  
 ******************************************************************/
window.addEventListener('load', async function () {
    console.log("no.7 ");
    //ここでは、まだ実行するのは、早い。glistobjがないため。
    const {commentInput,List} = await moduleWait;
    console.log("no.6 ");
    //これはテストで、クラスAAAをexportしている。
    gtestobj = new commentInput("これはテストです。");
    //window.gtestobj = gtestobj;
    // 動的に読み込まれたListクラス
    //export指定
    glistobj = new List("ランダムリスト");
    //ここで、auto_start()を実行するには、条件があり、必ず、先にglistobjが生成されていなければ
    //ならない。さもないとundefinedエラーになる。        
    auto_start("8ODcuS8bUuc");  //河内おとこ節
});

上は、しっかり、glistobjオブジェクトをセットしてから、auto_start(...)をコールしています。これで、不具合はなくなりました。

あとがき

デバッグしていて、難しいのは、やはり、上述のような不具合です。
デバックしていて気持ちがいいのは、ページをリクエストして、一発目で、必要な画面が表示され、同時に、各操作がスムーズに進んでゆくことです。エラーの発生がなく、何度繰り返しても正常に動作することです。
正常な処理は、あたり前ですが、処理の実行前に正しいデータが事前にセットされていることです。この当たり前のことが、デバッグ中は、特に慌てているときは、できていないために発生します。今回の教訓は、ダイナミックimportで、どのタイミングで、どの場所でファイルを読んで、初期設定をしたらいいのかを見極めることでした。

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?