加了type="module"仍报Cannot use import statement outside a module,说明脚本未被识别为模块:常见原因包括未加type="module"、内联script同时带src、外部JS未显式声明为模块,且file://协议下import必报CORS错误,必须用HTTP服务。

type="module" 不是加个属性就支持 import,它直接切换了整个脚本的执行模型——从传统 script 切换到 ES 模块加载器,行为差异大到不兼容。
为什么加了 type="module" 还报 SyntaxError: Cannot use import statement outside a module
这不是语法写错了,而是上下文没对上:
- 写了
import却放在没加type="module"的<script>里,浏览器按 classic script 解析,自然报错 - 动态
import()必须在模块上下文中调用,<script type="module">import('./a.js')</script>合法;但<script>import('./a.js')</script>即使加了async也非法 - 本地双击打开 HTML(
file://协议),Chrome/Firefox 直接拒绝发起请求,控制台只显示 CORS 错误或空错误,不是路径问题,是协议限制
import 路径必须带 .js 后缀,且不能省略 ./ 或 ../
ES 模块规范禁止自动补全或启发式解析,浏览器不会猜你指哪个文件:
-
import { foo } from './utils.js'✅ 绝对合法 -
import { foo } from './utils'❌ 报Failed to resolve module specifier -
import { foo } from 'utils.js'❌ 裸路径,无法判断是相对还是绝对,直接SyntaxError -
import { foo } from '/src/utils.js'✅ 绝对路径,从站点根目录解析
注意:Linux/macOS 下大小写敏感,Utils.js 和 utils.js 是两个不同模块。
立即学习“前端免费学习笔记(深入)”;
模块缓存和 HTTP 缓存完全两回事
改了文件内容却没生效?不是服务器没刷新,是 JS 引擎的 Module Map 锁死了旧导出:
- 模块缓存键是**完全解析后的绝对 URL**(含协议、域名、路径、查询参数),和
Cache-Control、ETag无关 - 哪怕服务器返回
Cache-Control: no-cache,模块仍被复用,顶层代码绝不再执行 - 想强制更新逻辑?必须改 URL —— 加哈希后缀(
main.abc123.js)或时间戳(main.js?v=20260723) -
modulepreload只下载不执行,也不影响 Module Map 命中,它只是提前把字节拉进内存
最容易被忽略的是:模块作用域隔离导致 window 上查不到任何顶层声明,document.currentScript 在模块里永远是 null,调试时别白费劲找它。



















