第二十三章 Module的加载实现

2019-01-12  本文已影响0人  A郑家庆

浏览器加载

传统方法

  默认情况下,浏览器同步加载javascript脚本,即渲染引擎遇到<script>标签就会停下来,等到脚本执行完毕再继续向下渲染。如果是外部脚本,还必须加入脚本下载的时间。如果脚本体积很大,下载和执行时间就会很长,因此造成浏览器堵塞,用户会感到浏览器卡死了,体验很不好,所以浏览器允许脚本异步加载,下面是两种异步加载语法:

<script src="path/to/myModule.js" defer></script>
<script src="path/to/myModule.js" async></script>

  defer与async的区别是,前者要等到整个页面正常渲染结束才会执行,而后者一旦下载完成,渲染与引擎就会中断渲染,执行这个脚本以后再继续渲染。用一句话来说,defer是"渲染完再执行",async是"下载完就执行"。另外如果有多个defer脚本,则会按照它们在页面出现的顺序加载,而多个async脚本是不能保证加载顺序的。

ES6模块与CommonJS模块的差异

  ES模块与CommonJS模块有两大差异:

总结:CommonJS模块特性有点像基本数据类型,在用require或module.exports引用进来的时候,新值和原始值互不影响;ES6模块特性有点像引用数据类型,在用export或export default引用进来的时候,改变新值或原始值,另外一个值也会改变,但是新值不能重新赋值。

import命令加载CommonJS模块

  Node采用CommonJS模块格式,模块的输出都定义在module.exports属性上面。在Node环境中,使用import命令加载CommonJS模块,Node会自动将module.exports属性当作模块的默认输出,即等同于export default,并且引用进来新值和原始值互不影响保持原来的特性,但是写法是ES6写法后面不能跟大括号。

require命令加载ES6模块

  采用require命令加载ES6模块时,ES6模块的所有输出接口都会成为输入对象的属性。

// es.js
export let foo = {bar: 'my-default'}
export function f() {}
// cjs.js
const es = require('./es.js')
console.log(es)
{
    get foo () {return foo}
    get f () {return f}
}

require和import都可以用来加载CommonJS和ES6模块,只不过写法和返回结果有一点不同。

总结:export加接口输出的模块用import后加上{}大括号引入,export default不加接口输出的模块用import后不加{}大括号引入,module.exports加等于号输出的模块用import可以加上大括号也可以不加大括号引入,加大括号表示解构赋值,不加大括号表示整体引入。

上一篇 下一篇

猜你喜欢

热点阅读