type="module"是最干净的模块化加载方式,具异步下载、延迟执行、顺序保障、自动严格模式及作用域隔离;须用外部文件、支持nomodule降级、强制CORS且不兼容IE。

直接说结论:用 type="module" 是当前最干净的模块化加载方式,它天然带 defer 行为、自动严格模式、作用域隔离,但必须配 src(不能内联使用 import),且不兼容 IE —— 如果要兼顾老浏览器,得用 nomodule fallback。
type="module" 脚本为什么能安全操作 DOM?
因为浏览器对 type="module" 的处理是:下载异步、执行延迟、顺序保障。它不会阻塞 HTML 解析,且总在 DOMContentLoaded 触发前执行 —— 即使写在 里,document.getElementById 也能直接调用,不用包事件监听。
- 必须是外部文件:
<script type="module" src="app.js"></script>合法;<script type="module">import {foo} from './a.js';</script>无效(无法解析import) - 路径必须是相对或绝对 URL,不支持 protocol-relative(如
//cdn.example.com/a.js) - 所有依赖会预加载,但执行仍按
import拓扑顺序串行,不是 HTML 标签顺序 - 变量默认不挂到
window,避免全局污染
async 和 defer 在 type="module" 上完全无效
写了也没用,浏览器直接忽略。比如:<script type="module" src="app.js" async defer></script> 中的 async 和 defer 不起作用 —— 模块脚本的加载与执行机制由 ES 模块规范定义,和传统脚本属性无关。
- 想实现“下载完立刻执行”的独立脚本(如统计代码)?改用普通脚本:
<script src="analytics.js" async></script> - 想确保多个模块按 HTML 顺序执行?只靠它们在文档中的位置即可,不需要额外加
defer - 动态创建的模块(
document.createElement('script')+type="module")会脱离静态执行队列,执行时机不可控,慎用
如何兼容不支持 module 的浏览器?
靠 nomodule 属性配对降级。浏览器会忽略带 nomodule 的脚本,当且仅当它不支持 type="module" 时才加载该脚本。
<script type="module" src="main.mjs"></script><script nomodule src="fallback.js"></script>
-
fallback.js必须是传统 IIFE 或 UMD 格式,不能含import/export - Webpack/Vite 默认输出的
.jsbundle 可直接用作nomodule入口 - 注意:Chrome 61+、Firefox 60+、Safari 10.1+ 支持
type="module";IE 完全不支持
最容易被忽略的一点是:模块脚本强制启用 CORS,哪怕同源也要加 crossorigin 属性才能捕获错误堆栈;而开发时本地 file:// 协议下模块根本无法加载 —— 这不是 bug,是规范限制,必须走 HTTP 服务。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











