绝大多数现代html场景下type属性可省略,浏览器默认按text/javascript解析;但type="module"必须显式声明以启用es模块特性,错误使用会导致语法错误或静默失败。

script 标签的 type 属性到底要不要写
绝大多数现代 HTML 场景下,type 属性可以省略 —— 浏览器默认按 text/javascript 解析,且所有主流浏览器都已原生支持 ES6+ 语法,无需显式声明。
但省略不等于“永远不写”。以下情况必须或建议保留:
- 使用非 JavaScript 脚本(如 TypeScript 编译前的
type="module"配合构建工具,或旧项目中遗留的type="application/typescript") - 明确标记模块脚本:
type="module"不仅改变解析行为(启用顶层 await、严格模式、相对 import),还影响作用域和加载时机 - 内联脚本中嵌入 JSON 数据(
type="application/json")或模板(type="text/template")—— 此时浏览器跳过执行,只作数据容器用
type="module" 和 type="text/javascript" 的行为差异
两者不是“语法糖替换”,而是触发完全不同的加载与执行模型。写错会导致脚本静默失败或报错。
常见错误现象:Uncaught SyntaxError: Cannot use import statement outside a module,往往是因为用了 import 却没加 type="module";或者加了 type="module" 却试图用 document.write 或访问 window 上挂载的变量(模块是封闭作用域)。
立即学习“前端免费学习笔记(深入)”;
-
type="module":自动启用defer行为(下载不阻塞解析,执行在 DOM 构建完成后)、支持import/export、基础 URL 是当前文档 URL(而非脚本路径) -
type="text/javascript"(或省略):按传统脚本执行,无模块特性;若要启用模块语法,必须加type="module" - 注意:
type="module"脚本无法通过document.createElement('script')动态插入后立即执行,需设置async=true或监听onload
兼容性陷阱:IE 和早期 Edge 怎么办
type="module" 在 IE 中完全不识别,会直接忽略;Edge 12–18 支持但有若干 bug(如不支持 import.meta.url)。如果还要兼容这些环境,不能只靠 type 切换。
- 不要用
type="module"+nomodule双脚本做降级:IE 会同时忽略二者,导致无脚本执行 - 真正可行的降级方案是:主脚本用
type="module",降级脚本用nomodule并确保它被现代浏览器跳过、旧浏览器执行 —— 但前提是你的构建流程能输出两套产物 - 更现实的做法:用打包工具(如 Vite、Webpack)统一输出一个传统脚本,彻底避开
type兼容问题;只有纯现代项目才放心用type="module"
script 标签里写 type="javascript" 会怎样
会出错。type="javascript" 不是标准值,浏览器不认识,可能当作未知类型跳过执行,也可能抛 Failed to execute 'importScripts' on 'WorkerGlobalScope' 类似错误(尤其在 Web Worker 中)。
正确写法只有三种:
- 省略
type(推荐,默认即 JS) -
type="text/javascript"(冗余但合法,HTML4 遗留写法) -
type="module"(现代模块脚本,必须配合 ES 模块语法)
其他任何变体,比如 type="js"、type="application/javascript"(虽在 MIME 规范中存在,但 HTML5 明确不鼓励)、type="javascript/ecmascript",都属于无效值,行为不可控。
最容易被忽略的一点:即使你用的是打包工具输出的单个 .js 文件,只要它内部含 import,就必须配 type="module";否则浏览器根本不会尝试解析 import 语句 —— 它不是“检测内容后决定是否启用模块”,而是“看到 type 才开启模块解析器”。











