必须用<script type="importmap">声明且置于<head>内所有type="module"脚本之前;type值严格为importmap(大小写敏感、无空格、不支持application/importmap等变体);必须内联JSON、不可用src或async;映射目标须为合法ES模块且响应头为application/javascript。

必须用 <script type="importmap"> 声明,且只能放在 <head> 或 <body> 开头、所有 type="module" 脚本之前,否则映射完全不生效。
type 属性必须严格写成 importmap,不能拼错或加空格
浏览器只识别 type="importmap" 这一种写法。写成 type="application/importmap"、type="text/importmap" 或漏掉 type 都会被忽略——不报错,但后续 import "lodash" 会直接抛 Failed to resolve module specifier。
常见错误包括:
-
<script type="importmap" src="importmap.json"></script>→ ❌ 不支持src,必须内联 JSON -
<script type="importmap" async></script>→ ❌ 不支持async、defer,必须同步解析 - 在
<script type="module">之后才写 importmap → ❌ 浏览器已开始解析模块,映射来不及加载
imports 字段的键和值都有硬性格式限制
键(裸模块名)必须是合法 bare specifier:全小写、无斜杠、不含点号,比如 "lodash"、"@vue/runtime-core" 合法;"lodash/debounce"、"index.js"、"MyLib" 都非法(子路径需靠 scopes 或 CDN 的 exports 字段支持)。
立即学习“前端免费学习笔记(深入)”;
值(映射目标)必须是:
- 完整 HTTPS URL(线上环境)或 HTTP URL(仅限
localhost),如"https://esm.sh/react@18.2.0" - 以
/、./或../开头的相对路径,如"./src/utils.js"、"/js/lodash.esm.js" - ❌ 不能是裸文件名:
"lodash.js"、"node_modules/lodash/index.js"会被静默忽略
注意:相对路径是相对于当前 HTML 页面 URL 解析的,不是相对于 importmap 所在位置。
CDN 路径必须返回真正的 ESM 模块,否则运行时报错
即使 URL 可访问、状态码 200,如果响应头没设 Content-Type: application/javascript,或脚本本身是 CommonJS/UMD 格式(没有 export),浏览器会在执行时卡在 TypeError: Cannot assign to read only property 'exports' 或类似错误。
推荐使用明确输出 ESM 的 CDN:
-
https://esm.sh/lodash@4.17.21(自动转译 + 正确 MIME) -
https://cdn.skypack.dev/react@18.2.0(原生 ESM) -
https://cdn.jsdelivr.net/npm/lodash@4.17.21/+esm(加+esm后缀) -
https://unpkg.com/lodash@4.17.21?module(加?module)
避免使用未标注 ESM 的链接,例如 https://cdn.jsdelivr.net/npm/lodash@4.17.21 默认返回 CJS,必报错。
用 scopes 处理局部版本冲突时,匹配逻辑容易被误解
scopes 的 key 是发起 import 的模块所在路径前缀(必须以 / 或 ./ 开头),不是被 import 的包名。比如:
{"imports": {"lit": "https://esm.sh/lit@3.1.0"},
"scopes": {"./src/legacy/": {"lit": "https://esm.sh/lit@2.8.0"}}}
只有当某个 import "lit" 是从 ./src/legacy/some-component.js 里写的,才会命中 scopes 规则,用 lit@2.8.0;其他地方仍走 imports 的 lit@3.1.0。
关键细节:
-
scopes的 key 必须以/或./开头,且建议以/结尾(如"./src/legacy/"),否则可能匹配不精确 - 一个模块导入时,先查 scopes 中匹配其调用者路径的规则,没命中才 fallback 到
imports - 不支持通配符或正则;
"lodash/*"这种写法只在部分 CDN 支持,importmap 本身不解析通配
最易忽略的一点:importmap 是静态声明,无法动态更新或条件加载——上线前必须逐条验证每个 URL 是否真实可访问、是否返回合法 ESM、是否同源(本地调试时尤其注意 file:// 协议被禁用)。



















