javascript的esmodules如何与html整合_使用type=“module”时要注意什么【教程】

9次阅读

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

javascript的esmodules如何与html整合_使用type=“module”时要注意什么【教程】

直接用 就能加载 ES 模块,但默认是严格模式、不共享全局作用域、路径必须带扩展名或以 / ./ ../ 开头——这些不是可选项,是浏览器强制要求。

为什么 的 import 路径不能省略扩展名?

ESM 的解析规则要求模块说明符(specifier)必须是有效的 URL。浏览器不会像 node.js 那样自动补 .js,也不会查 package.jsonexports 字段。

  • 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/firefoxfile:// 协议下加载模块有更严格的 CORS 策略。即使所有文件都在同一目录,import 也会被拦截。

立即学习Java免费学习笔记(深入)”;

  • 错误信息典型为:access to script at 'file:///.../utils.js' from origin 'NULL' has been blocked by CORS policy
  • 唯一可靠解法:起一个本地服务器,比如 npx servepython3 -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 其他模块,则依赖链优先于书写顺序。别假设“写在下面的模块一定后执行”。

text=ZqhQzanResources