前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库import map 模块说明符映射作用
JavaScript模块与语言机制

import map 是干什么的?有了它浏览器怎么解析 import 'vue'?

import map 是写在 <script type="importmap"> 里的一段 JSON,给模块说明符做查找表。浏览器遇到 import "vue" 时先查这张表,把 vue 换成表里的 URL 再去加载,不用打包也能写裸模块名。

前端进阶之旅 · 一题精讲更新于 2026.09.29
JavaScript#模块与语言机制
先看核心答案读代码示例
理解线索

import map 的三块内容

  1. imports全局查找表,"vue" 映射到某个 CDN 地址
  2. scopes某个目录下的模块用另一套映射,解决版本冲突
  3. 前缀映射"lodash/" 这种以斜杠结尾的键,匹配所有子路径

import map 只改说明符的解析结果。模块照样一个个发请求,依赖多了请求数会很多,生产环境大项目通常还是打包。

核心回答

先记住这个答案

浏览器原生 ESM 只认完整 URL 和 ./、../ 或 /src/a.js 这类路径,import { ref } from "vue" 这种裸说明符会直接报错。import map 就是一张查找表,写在 <script type="importmap"> 里,浏览器解析每个说明符前先查表,把 vue 替换成表里对应的 URL 再加载。它只改变「说明符到 URL」这一步,模块的加载和执行方式不变。

  • import map 把模块名映射到 URL
  • scopes 可覆盖局部解析规则
  • 键以斜杠结尾是前缀映射,能覆盖子路径
  • 必须在第一个用到它的模块脚本之前出现

一个不用打包也能写裸模块名的页面

最常见的用法是配合 CDN,让业务代码里的导入写法和在 Node.js 项目里一样。

imports 和前缀映射HTML
<script type="importmap">
  {
    "imports": {
      "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js",
      "lodash-es/": "https://cdn.jsdelivr.net/npm/lodash-es/",
      "@/": "/src/"
    }
  }
</script>

<script type="module">
  import { createApp } from 'vue' // 解析成上面的 unpkg 地址
  import debounce from 'lodash-es/debounce.js' // 前缀映射,拼成完整地址
  import { api } from '@/api.js' // 解析成 /src/api.js
</script>

imports 里有两种键。不带斜杠结尾的是精确匹配,vue 只匹配 vue 本身。以斜杠结尾的是前缀映射,lodash-es/ 会匹配所有以它开头的说明符,把前缀替换掉,剩下的路径原样拼上去。前缀映射的值也必须以斜杠结尾,否则这条映射无效。 @/ 那条说明 import map 也能当路径别名用,效果类似打包器里的 alias。

用 scopes 解决版本冲突

有时两个库依赖同一个包的不同版本。imports 是全局的,只能给出一个答案,这时就需要 scopes。

按目录覆盖映射
scopes 的键是一个 URL 前缀,值是一张新的查找表。发起导入的模块 URL 落在这个前缀下时,先查这张表,查不到再回到全局的 imports。比如全局把 lodash-es/ 映射到新版本,同时在 scopes 里写 "/legacy/": { "lodash-es/": "https://cdn.example.com/lodash-es@4.17.0/" },那么 /legacy/ 目录下的模块导入 lodash 时拿到的是旧版本,其它模块不受影响。 这个机制和 Node.js 里每个包有自己的 node_modules 很像,只不过浏览器没有文件系统可以逐层查找,只能由你把规则写死。
回答前,多想一步

容易答错的地方

以为 import map 放在哪里都行
import map 必须在第一个需要它的模块开始解析之前出现。模块脚本已经加载后再插入 import map,对已经发起的解析不生效,浏览器会在控制台给出警告。稳妥的做法是把它放在 <head> 里所有模块脚本之前。
以为 import map 能替代打包
它只解决「写裸模块名」这一件事。每个模块依然是单独一个请求,依赖树深的库会产生大量请求,也没有 tree shaking 和压缩。小工具、演示页、内部系统可以直接用,大型生产项目通常还是走打包器。
以为它会改写页面上所有请求
import map 作用于静态 import、动态 import() 以及 import.meta.resolve。普通的 <script src>、fetch、<link> 这些请求不会查这张表。
试着用自己的话回答

面试官还会怎么问?

Node.js 为什么不需要 import map?

Node.js 有自己的解析算法:遇到裸说明符就从当前目录开始逐层往上找 node_modules,再读包的 package.json 里的 exports 或 main。浏览器只能通过网络请求,一层层去试探不存在的 URL 代价太高,所以只能靠显式映射。

import map 能用 src 引用外部文件吗?

目前规范不支持 <script type="importmap" src="...">,只能内联写 JSON。需要动态生成时,可以在服务端渲染页面时输出,或者在任何模块脚本执行前用 JS 创建一个内联的 importmap 标签插进去。

在 Vite 或 Webpack 项目里会用到 import map 吗?

平时开发基本不用手写,它们在构建时已经把裸说明符改写成了具体路径。import map 常出现在微前端里:多个子应用共享同一份 Vue 或 React,由基座页面用 import map 统一指定版本,子应用构建时把这些依赖标成外部依赖。

从一道题,走向一组知识

把知识连起来

模块与语言机制

import.meta.resolve 是干什么的?它和 import 有什么关系?

import.meta.resolve 会按 import map 解析说明符,是查看映射结果最直接的办法。

模块与语言机制

import.meta.url 在浏览器和 Node.js 里分别拿到的是什么?

相对路径是基于当前模块的 import.meta.url 解析的,import map 管的则是裸说明符。

参考资料

  • JavaScript:模块与语言机制参考资料

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 一个不用打包也能写裸模块名的页面
  3. 用 scopes 解决版本冲突
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑