type="module"脚本默认具备更严格的defer行为,执行时机严格绑定domcontentloaded前一刻,按依赖拓扑顺序串行执行,拥有独立作用域、自动严格模式、禁用document.write、强制cors及支持顶层await。

type="module" 的脚本默认就具备 defer 行为,无需显式写 defer 属性,但它的“延迟”逻辑比传统 defer 更严格、更可靠。
执行时机完全等价于 DOMContentLoaded
模块脚本在 HTML 解析完成、DOM 树构建完毕后才开始执行,不依赖下载快慢——哪怕某个模块体积小、先下载完,也必须等到整个文档解析结束才能运行。这和传统 defer 一致,但模块脚本的执行时机被规范强制绑定到 DOMContentLoaded 前一刻,不会因浏览器实现差异而偏移。
顺序执行由模块图决定,不是靠 DOM 位置模拟
多个 <script type="module"></script> 按它们在 HTML 中出现的顺序执行,即使其中某一个依赖了远端或深层嵌套的模块,浏览器也会等待整个依赖链解析完成后再推进到下一个 script 标签。
一款AI工具,主要用于一款基于 Rust 的快速无头浏览器自动化命令行工具(CLI),支持 Node.js 回退机制,可使 AI agent 通过结构化命令实现页面导航、点击、输入及截图,适合需要提升相关任务效率的用户。
- 这意味着:A.js → import B.js,B.js → import C.js,那么 A、B、C 的执行一定串行,且整体排在下一个独立模块脚本之前
- 传统
defer脚本只是按标签顺序下载+执行,不检查内部 import 关系;模块脚本把“顺序”升级为“依赖拓扑顺序”
天然隔离,不污染全局作用域
每个模块拥有独立的顶层作用域,const、function、class 等声明不会自动挂到 window 上,也不共享变量。这点和传统 defer 脚本完全不同——后者仍运行在全局上下文中,容易引发命名冲突或意外覆盖。
- 例如:
<script defer>const foo = 123;</script>之后,window.foo是可访问的 - 而
<script type="module">const foo = 123;</script>中的foo完全不可见于全局
其他默认特性强化了 defer 的可靠性
模块脚本还自带多项约束,共同保障延迟执行的稳定性和安全性:
- 自动启用严格模式(不用写
"use strict") - 禁止使用
document.write(),避免破坏 DOM 构建流程 - 必须遵循 CORS 策略,跨域模块需服务端明确允许
- 支持顶层
await,可直接等待异步初始化完成再继续执行后续模块逻辑










