nomodule不是降级开关,而是现代浏览器的“跳过指令”,必须与type="module"成对使用;单独使用会导致新旧浏览器均白屏,因现代浏览器跳过、ie11等旧浏览器静默忽略整行标签而不执行脚本。

nomodule 不是降级开关,它只在不支持 type="module" 的浏览器中执行;单独使用会导致现代和旧版浏览器都白屏——现代浏览器跳过,旧浏览器(如 IE11)静默忽略整行标签,脚本根本不加载。
为什么 <script nomodule src="fallback.js"></script> 在 IE11 里没反应
IE11 不识别 nomodule 属性,但它也**不执行该 <script></script> 标签**。这不是 bug,而是 HTML 规范行为:遇到无法识别的布尔属性且无合法 type 值时,整个元素被跳过解析。结果就是:Chrome/Firefox/Safari 不发请求、不执行;IE11 也不执行——页面 JS 彻底断掉。
验证方法:
- Chrome DevTools Network 面板搜
fallback.js,它不该出现(说明被跳过) - IE11 控制台执行
typeof module返回"undefined",但fallback.js里的console.log也没输出,基本可判定是单写nomodule导致的丢弃
必须和 type="module" 成对出现才能生效
只有两者并存,才构成真正的双路径加载逻辑:
<script type="module" src="app.mjs"></script><script nomodule src="legacy-bundle.js"></script>
执行逻辑:
- 现代浏览器(Chrome 61+、Firefox 60+、Safari 11+、Edge 16+):加载并执行
app.mjs,跳过legacy-bundle.js(不发网络请求) - 旧浏览器(IE11、Android 4.4 WebView、Safari 10.1):忽略
type="module",不加载app.mjs;不识别nomodule,但会照常加载并执行legacy-bundle.js
注意:nomodule 脚本在旧浏览器中默认同步阻塞 HTML 解析,建议显式加 defer:
<script nomodule defer src="legacy-bundle.js"></script>
legacy-bundle.js 必须是真·ES5 + 手动 polyfill
nomodule 只管“要不要加载”,不管“能不能跑”。哪怕脚本进了 IE11,以下任一情况都会立刻崩溃:
- 语法层面:含
const、let、=>、${}、class→ 直接SyntaxError - API 层面:调用
fetch()、Promise、Array.from()、Object.assign()→ReferenceError或静默失败 - DOM 层面:用
element.classList.add()(IE9–)、querySelector()(IE7–)、addEventListener()(IE8–)→ 报错或无响应
实操要点:
- 构建时显式设
targets: { ie: "11" },不能依赖 Babel 默认 preset -
core-js/stable需手动引入,且 polyfill 必须在所有业务代码之前执行 - 输出格式只能是 IIFE 或 UMD,严禁含
import/export,禁用dynamic import() - 避免在
legacy-bundle.js中做 UA 判断再异步加载 polyfill——IE11 解析慢,极易超时或失败
最容易被忽略的一点:即使你写了正确的双 <script></script> 结构,只要 legacy-bundle.js 里有一行 const x = 1,IE11 就会在第一行报错并中断执行——它不会像现代浏览器那样有错误边界或容错机制,语法错误即终止。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











