2017-08-29 14 views
1

Webpackは、動的インポート用にECMAScript proposalに準拠するimport()構文をサポートしています。この構文は、モジュールを非同期にロードすることを約束します。ダイナミックモジュールとそのすべての依存関係がロードされたときを検出するにはどうすればよいですか?

問題は、モジュールの依存関係がロードされるのを待つことなく、特定のモジュールがロードされるとすぐに解決されるということです(JS & CSSを含むあらゆる種類のアセットが可能です)。

例コード:

import('./myModule.js').then(myModule => { 
    myModule.sayHello(); // This will be called before someCSS.css has been loaded 
}); 

myModule.js

import './someCSS.css'; // <-- I need to know when this is loaded (there can be more than one asset) 

export default class myModule { 
    sayHello() { 
     alert('Hello!'); 
    } 
} 

モジュール、および関連するすべての資産は、ロードされたとき、どのように私は検出することができますか?非同期アセットのonloadイベントのようなものはありますか?

答えて

0

方法は、あなたが決定することを可能にする約束を返すスクリプトがロードされたか、(例えば)のロード中にエラーが発生したかどうか:

// utils.js 
function insertJs({src, isModule, async, defer}) { 
    const script = document.createElement('script'); 

    if(isModule){ 
     script.type = 'module'; 
    } else{ 
     script.type = 'application/javascript'; 
    } 
    if(async){ 
     script.setAttribute('async', ''); 
    } 
    if(defer){ 
     script.setAttribute('defer', ''); 
    } 

    document.head.appendChild(script); 

    return new Promise((success, error) => { 
     script.onload = success; 
     script.onerror = error; 
     script.src = src;// start loading the script 
    }); 
} 

export {insertJs}; 

//An example of its use: 

import {insertJs} from './utils.js' 

// The inserted node will be: 
// <script type="module" src="js/module-to-be-inserted.js"></script> 
const src = './module-to-be-inserted.js'; 

insertJs({ 
    src, 
    isModule: true, 
    async: true 
}) 
    .then(
     () => { 
      alert(`Script "${src}" is successfully executed`); 
     }, 
     (err) => { 
      alert(`An error occured during the script "${src}" loading: ${err}`); 
     } 
    ); 
// module-to-be-inserted.js 
alert('I\'m executed'); 
+0

スクリプトは関係なく、その依存関係の、ロードされたときの約束が解決されていますCSSStyleSheetオブジェクトを使用すると、その反対チェックする約束を作成できるようにスタイルシートは、ロードされた一度だけcssRulesプロパティが含まれます。詳細については、私の更新を参照してください。 –

+0

@ YoavKadoshあなたは設計上問題があります。子モジュールの依存関係です。親モジュールはそれらに頼るべきではありません。これらの依存関係が必要な場合は、親モジュールもそれらの依存関係をインポートする必要があります。 – estus

+0

親モジュールでは不要です。私は彼らがスピナーを隠すためにいつ利用可能であるかを知る必要があります。 –

0

それはチェックするdocument.styleSheetsを使用することが可能ですすべてのスタイルシートがロードされたとき。

export function awaitStylesheets() { 
    let interval; 
    return new Promise(resolve => { 
     interval = setInterval(() => { 
      for (let i = 0; i < document.styleSheets.length; i++) { 
       // A stylesheet is loaded when its object has a 'cssRules' property 
       if (typeof document.styleSheets[i].cssRules === 'undefined') { 
        return; 
       } 
      } 

      // Only reached when all stylesheets have been loaded 
      clearInterval(interval); 
      resolve(); 
     }, 10); 
    }); 
} 
関連する問題