ESM 语法
模块标签与普通脚本的执行顺序如何?
- 顺序: 先执行所有普通
script, 再按出现顺序执行模块标签;
<script type="module">
/* 第二个执行 */
</script>
<script type="module" src="path/to/myModule.js"></script>
<script>
/* 第一个执行 */
</script>
- 原因: 模块默认延迟执行, 等价于
defer的时机, 见 脚本加载与文档模式;
工作者线程如何使用模块?
new Worker("scriptWorker.js"); // 默认 { type: "classic" }
new Worker("moduleWorker.js", { type: "module" });
如何导出模块成员?
- 命名导出: 一个模块可以有多个; 用
as起别名; - 默认导出: 一个模块最多一个;
const foo = "foo";
const bar = "bar";
export { foo, bar as myBar };
export default foo;
export { foo as default }; // 等同于 export default foo;
如何导入模块成员?
import foo from "./foo.js"; // 默认导出
import { default as foo } from "./foo.js"; // 默认导出的另一种写法
import { bar, baz } from "./foo.js"; // 命名导出
import * as Foo from "./foo.js"; // 命名空间对象
- 静态约束: 导入语句只能在模块顶层, 且导入名必须在解析阶段可确定;
如何转移导出?
export * from "./foo.js"; // 全部命名导出
export { foo, bar as myBar } from "./foo.js"; // 按名与别名
export { default } from "./foo.js"; // 复用默认导出
export { foo as default } from "./foo.js"; // 命名导出转为默认导出
- 运行时行为与循环依赖表现见 ESM 加载机制;