2017-08-29 41 views
1

Webpack支持符合動態導入的ECMAScript proposalimport()語法。該語法使用承諾異步加載模塊。如何檢測動態模塊及其所有依賴項何時加載?

的問題是,許被只要特定模塊被加載解決,而不等待模塊的依賴關係來加載(其可以是任何類型的資產,包括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

當腳本加載的承諾得到解決,無論其依賴關係。查看我的更新以獲取更多信息。 –

+0

@YoavKadosh然後你有設計問題。這些是子模塊的依賴關係。父模塊不應該依賴它們。如果它需要這些依賴關係,父模塊也應該導入它們。 – estus

+0

它們在父模塊中不需要。我需要知道他們何時可以隱藏微調器。 –

0

它可以使用document.styleSheets檢查當所有樣式表都被加載時。一個CSSStyleSheet對象將包含一次樣式表已加載的cssRules屬性,因此你可以創建檢查針對一個承諾:

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); 
    }); 
} 
相關問題