的 import 路径必须带扩展名或以 / ./ ../ 开头,因 ESM 要求模块说明符为有效 URL,浏览器不自动补 .js 或解析 package.json;模块有独立顶层作用域,无法访问非模块脚本挂载的 window 变量;本地 file:// 协议下会触发 CORS,需用本地服务器;模块默认 defer 但执行顺序依依赖链而非 HTML 位置。

直接用 就能加载 ES 模块,但默认是严格模式、不共享全局作用域、路径必须带扩展名或以 / ./ ../ 开头——这些不是可选项,是浏览器强制要求。
为什么 的 import 路径不能省略扩展名?
ESM 的解析规则要求模块说明符(specifier)必须是有效的 URL。浏览器不会像 Node.js 那样自动补 .js,也不会查 package.json 的 exports 字段。
-
import { foo } from 'utils'→ ❌ 报错:Failed to resolve module specifier 'utils' -
import { foo } from './utils.js'→ ✅ 正确(注意.js) -
import { foo } from '/src/utils.js'→ ✅ 绝对路径也行 -
import { foo } from 'https://cdn.skypack.dev/lodash-es'→ ✅ 远程 URL 也合法
type="module" 脚本里无法访问 window 上挂的变量?
模块脚本有独立的顶层作用域,和传统 的全局作用域隔离。你在非模块脚本里写的 window.myLib = {...},在模块里读不到 window.myLib,哪怕它先执行。
- 模块内
console.log(myLib)→ReferenceError - 模块内
console.log(window.myLib)→undefined(即使它确实存在) - 解决办法只有显式导出:把逻辑封装进
myLib.js,再用import { something } from './myLib.js' - 别试图用
export * from 'data:,'或动态eval绕过——既不可靠也不符合 ESM 设计意图
开发时遇到 CORS 错误,但文件明明在本地?
Chrome/Firefox 对 file:// 协议下加载模块有更严格的 CORS 策略。即使所有文件都在同一目录,import 也会被拦截。
立即学习“Java免费学习笔记(深入)”;
- 错误信息典型为:
Access to script at 'file:///.../utils.js' from origin 'null' has been blocked by CORS policy - 唯一可靠解法:起一个本地服务器,比如
npx serve或python3 -m http.server 8000 - VS Code 插件 Live Server 也行,但注意它默认用
http://127.0.0.1:5500,确保你的 HTML 中的 import 路径与之匹配(如./src/main.js) - 不要用
chrome --disable-web-security—— 它禁用的是整个安全模型,不是调试方案
index.html
最常被忽略的一点:模块脚本默认是 defer 行为(即 DOM 解析完才执行),但它**不保证执行顺序**——多个 type="module" 脚本之间,只按 HTML 中出现顺序执行;但若某个模块内部又 import 其他模块,则依赖链优先于书写顺序。别假设“写在下面的模块一定后执行”。











