模块就是一个包含JS代码的文件,因此模块本质上就是一段脚本,但是模块与脚本还是有两点区别:
①在ES6模块中,无论你是否加入use strict;语句,默认情况下模块都是在严格模式下运行。
②在模块中可以使用import和export关键字。
export
默认情况下,某个模块中的所有声明相对于本模块而言都是寄存在本地的,只有本模块可见,其他模块不可见。但如果想让其他模块使用本模块的部分功能,最简单的方式就是在想要公开内容的前面加上export关键字。而export关键字可以修饰最外层函数、类class、 var变量、let变量、const变量。
如果你需要export的内容比较多,在每个内容前面添加export比较繁琐,那么可以使用下面语法来简化代码量:
export {公开内容名1, ...公开内容名N};
export列表可以在模块文件最外层作用域的每一处声明,不一定非要把它放在模块文件的首行。也可以声明多个export列表,甚至通过其它的export声明打造一个混合的export列表,但是只要保证每一个被导出的名称是唯一的即可。
import
如果想引用其他模块所公开的内容,那么语法如下:
import {公开内容名1, ...公开内容名N} from "文件名.js";
重命名import和export
如果你export/import的内容与其他已存在的内容冲突时可以这么处理:
import { xxx1 as xxx2} from "xxx.js";
export { yyy1 as yyy2};
说白了,就是使用as关键字对公开内容/导入内容进行重命名操作。
默认导出
export {myObject as default};
export default { field1: value1, field2: value2 };
关键字export default后可跟随任何值:一个函数、一个类、一个对象字面量等等,注意是任何值,任何值。
模块对象
import * as tests from "tests";
import *的含义就是把tests模块中所有export都一次性导入了,因此如果想调用tests模块的内容,只能这么使用:tests.公开内容名字。
聚合
export * from "xxxx";
export {xxx1, ...xxx2} from "xxx";
这里用的是export-from,那么export-from与export区别在于:
export单纯就是把xxx导出;
export-from是首先把from后面模块的导出内容导入到当前模块,然后当前模块再把导入的内容再重新导出。这些导入再重新导出的内容并不会在当前模块作用域中绑定导入的内容,即当前模块无法调用export-from所导入的内容。
那么export-from干什么用呢?我也不知道。
注意事项
①一个模块的所有依赖必须在模块代码运行前完全加载、解析并且及早连接,不存在一种通过import来按需懒加载的语法。
②import模块产生的错误没有错误恢复机制。一旦有一个模块无法加载或连接,则其他所有的模块都不会运行,而且你不能在 try/catch 代码块中捕捉import的错误信息。
③无法控制模块的依赖加载过程。