2017-08-29 63 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); 
    }); 
} 
相关问题