es6 module加载机制

370 阅读2分钟

1.浏览器加载js的方式

< script src=“module.js”>< /script >
如果module.js的体积过大,久会导致加载和执行的时间很长,导致浏览器卡死。因此出现了两种’异步加载’js的方式。defer和async

异步加载即: 浏览器遇到脚本先下载,但是并不会等待下载完成,而是直接执行后面的代码。

< script src=“module.js” defer>< /script >
< script src=“module.js” async>< /script >

defer:要等到整个页面在内存中正常渲染结束(DOM 结构完全生成,以及其他脚本执行完成),才会执行,即:渲染完再执行
async:一旦下载完,渲染引擎就会中断渲染,执行这个脚本以后,再继续渲染。即: 下载完就执行。

另外,如果有多个defer脚本,会按照它们在页面出现的顺序加载,而多个async脚本是不能保证加载顺序的

浏览器加载 ES6 模块,也使用< script >标签,但是要加入type="module"属性,type="module"属性等价于开启了defer属性。
这种方式加载的js自动开启严格模式,‘use strict’,脚本顶层的this指向undefined而不是window.

2.es6和CommonJs加载模块的区别。

CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。
CommonJS 模块的require()是同步加载模块,ES6 模块的import命令是异步加载,有一个独立的模块依赖的解析阶段。

3.循环依赖

循环加载:a.js依赖于b.js文件,b.js文件又依赖于a.js文件。

CommonJS 模块的循环加载:CommonJS模块在执行requre的时候就会执行,一旦出现某个模块被"循环加载",就只输出已经执行的部分,还未执行的部分不会输出。

es6模块的循环加载:如果使用import从一个模块加载变量(即import foo from ‘foo’),那些变量不会被缓存,而是成为一个指向被加载模块的引用,需要开发者自己保证,真正取值的时候能够取到值。