importmap 是浏览器原生支持的模块映射机制,chrome 89+、firefox 109+、safari 16.4+ 原生支持,通过 声明 json 映射,实现裸模块名到 url 的重写,无需构建工具。

importmap 是浏览器原生支持的模块映射机制,能让你用简洁的模块名(比如 "lodash")代替冗长的 URL(比如 "https://cdn.jsdelivr.net/npm/lodash@4.17.21/index.js"),且无需构建工具。但它目前只在 Chromium 94+、Firefox 109+ 和 Safari 16.4+ 中可用,**不支持动态更新或运行时修改**。
怎么写一个合法的 importmap 块
必须是 <script type="importmap"></script>,放在 中(执行顺序敏感,要早于任何 import 脚本)。内容是标准 JSON,顶层只有 "imports" 字段("scopes" 可选但更复杂):
{
"imports": {
"react": "https://esm.sh/react@18.2.0",
"react-dom": "https://esm.sh/react-dom@18.2.0",
"utils": "./src/utils.js"
}
}
注意:type="importmap" 是强制的;JSON 中不能有注释;URL 必须是完整路径(相对路径会被解析为相对于当前 HTML 文档);键名不能以 / 开头,否则会被视为“范围映射”而非“裸 specifier”。
import 语句里怎么用映射后的名字
只要 importmap 已加载,后续所有 import 都可直接使用映射名——它和 ESM 规范完全兼容:
import { debounce } from "lodash";
import App from "app";
import { log } from "utils";
这些不会触发 404,前提是 importmap 里已声明对应键。常见错误包括:
- 在
importmap前就执行了import(比如<script type="module"></script>放在<script type="importmap"></script>上方) - 拼错映射名(如写成
"Lodash"但映射表里是"lodash") - 试图用映射名动态
import()但未加引号(import("lodash")✅,import(lodash)❌)
scopes 能解决什么问题
当不同模块依赖同一包的不同版本,或你想为某个路径下的所有导入统一重写来源时,"scopes" 比 "imports" 更精准:
{
"imports": {
"vue": "https://esm.sh/vue@3.3.4"
},
"scopes": {
"./node_modules/legacy-app/": {
"vue": "https://esm.sh/vue@2.7.14"
}
}
}
这样,只有从 ./node_modules/legacy-app/ 下发起的 import "vue" 才会命中 Vue 2,其他地方仍走 Vue 3。但要注意:scopes 的 key 必须是绝对路径或以 ./ 或 ../ 开头的相对路径;它不支持通配符或正则;且每个 scope 的匹配基于导入语句的 **引用者路径**,不是被导入模块的路径。
真正麻烦的是调试:浏览器开发者工具的 Sources 面板里看不到映射过程,出错时控制台报的仍是原始 specifier(比如 Failed to load module "lodash"),但实际请求的 URL 已被替换——你得手动查 importmap 内容并比对网络面板里的真实请求地址。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











