nomodule属性仅被现代浏览器识别并跳过含该属性的script标签,旧浏览器因不识别而执行它;必须与type="module"配合使用才能实现双路径加载,且fallback.js需兼容es5、api及执行时机。

nomodule 属性只对现代浏览器生效
现代浏览器(Chrome 61+、Firefox 60+、Safari 11+、Edge 16+)遇到 nomodule 属性会跳过该 <script></script> 标签;旧浏览器(如 IE11、Edge 15 及更早、Android Browser 4.4)不识别 nomodule,会照常加载并执行它。这是它的设计逻辑——不是“给旧浏览器用”,而是“让旧浏览器不得不执行它”。
所以,nomodule 本身不提供“回退”能力,它只是配合 type="module" 实现模块脚本的条件加载。
必须搭配 type="module" 才能形成有效分流
单独写 <script nomodule src="fallback.js"></script> 没有意义:旧浏览器会加载它,但现代浏览器也会加载(因为没加 type="module",它被当作普通脚本处理,nomodule 被忽略)。正确写法是成对出现:
<script type="module" src="app.mjs"></script><script nomodule src="fallback.js"></script>
这样才构成真正的双路径:
- 现代浏览器:执行
app.mjs(ES module),跳过fallback.js - 旧浏览器:忽略
type="module"(不支持),跳过app.mjs;识别不到nomodule,于是加载并执行fallback.js
fallback.js 必须是完全兼容的 ES5 代码
旧浏览器(尤其是 IE11)不支持箭头函数、const/let、模板字符串、async/await、class 等语法,也不支持 import/export。哪怕 fallback 脚本里有一行 const x = 1;,IE11 就会直接报 SyntaxError 并中断执行。
实操建议:
- 用 Babel + preset-env 编译,目标设为
"ie 11" - 避免使用
fetch,改用XMLHttpRequest或引入whatwg-fetchpolyfill(且需在 fallback.js 内提前加载) - 不要在 fallback.js 中动态 import(),旧浏览器不支持
- 确保所有依赖(如 React、Vue)也提供 UMD 或 IIFE 版本,并与 fallback.js 同构打包
注意 script 加载顺序和执行时机差异
type="module" 脚本默认是 defer 行为(按文档顺序执行,不阻塞 HTML 解析),而 nomodule 脚本在旧浏览器中表现和普通 <script></script> 一样:若无 defer 或 async,会同步阻塞解析。
为保持行为一致,推荐显式控制:
- 现代路径:
<script type="module" src="app.mjs"></script>(已 defer) - 旧路径:
<script nomodule defer src="fallback.js"></script>(显式加defer,避免阻塞)
否则 fallback.js 可能在 DOM 尚未就绪时就运行,导致 document.getElementById 返回 null 等问题。
真正容易被忽略的是:nomodule 不是 polyfill 开关,它不触发任何自动降级逻辑;你得自己保证 fallback.js 在语法、API、执行时机三方面都经得起旧环境考验——漏掉任意一环,回退就变成白屏或报错。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











