ES Modules 的本质是解决全局污染与隐式依赖问题:每个.js文件为独立作用域,仅通过export/import通信;import/exports必须顶层静态声明;支持命名导出({}导入)与默认导出(任意名导入);依赖图静态构建、深度优先执行;常见坑包括动态import、空解构、路径缺扩展名等。

画 ES Modules 的思维导图,重点不在画得漂亮,而在于理清模块系统的逻辑骨架——它解决什么问题、怎么组织代码、有哪些关键规则、常见误区在哪。下面按实用路径分四块展开,每块都对应导图中的一个主分支。
模块的本质:为什么需要 import/export
ES Modules 不是语法糖,而是为了解决全局污染和依赖隐式的问题。早期靠 script 标签顺序加载,jQuery 插件必须等 jQuery 先挂到 window 上;一旦顺序错、变量被覆盖或重复定义,运行时就崩。模块把“谁提供什么”和“谁用什么”显式写进代码里,让依赖可追踪、可静态分析。
- 每个 .js 文件默认是一个独立模块作用域(顶层 this 是 undefined,不是 window)
- 模块间通信只靠 export / import,没有全局泄露
- import 声明在编译阶段解析(hoisted),且不可动态执行(不能写在 if 里)
核心语法结构:export 和 import 的写法组合
导图中间节点建议用“导出方式 ↔ 导入方式”对照呈现,避免混淆命名导出与默认导出的匹配关系。
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
-
命名导出(named export):可多个,必须用大括号导入,名称要一致
export const apiURL = 'https://api.example.com';
export function fetchData() { … }
import { apiURL, fetchData } from './utils.js'; -
默认导出(default export):每个模块最多一个,导入时名字任意
export default class Router { … }
import MyRouter from './router.js'; // 不用大括号 -
混合使用:可同时有 default + named,但 import 要分开写
import Router, { history, navigate } from './router.js';
加载机制:静态分析 + 依赖图 + 执行顺序
这是理解模块行为的关键,也是面试常考点。导图中可用箭头示意“解析 → 构建图 → 执行”三阶段。
- 浏览器或 Node.js 启动时,先递归解析所有 import,生成一棵单向依赖树(无循环则成功,有循环则报错)
- 所有模块代码在执行前先求值(evaluate),但只执行一次(即使被多次 import)
- 执行顺序是深度优先、从入口开始,父模块总在子模块之后运行(即“先子后父”)
- 动态 import() 是函数调用,返回 Promise,可用于按需加载(如路由懒加载)
实际开发避坑点:常见错误与写法边界
这部分适合作为导图末梢的警示标签,贴在对应语法节点旁。
- 不能在 if 或函数内写静态 import(会报 SyntaxError)
- export {} 是合法的,但 import {} from 'x' 会报错(空对象解构不匹配)
- Node.js 中 .mjs 后缀或 package.json 设置 "type": "module" 才启用 ESM;.js 默认是 CommonJS
- 浏览器中 script 标签必须加 type="module",否则当作普通脚本忽略 import/export
- 路径必须带扩展名(./utils.js),不能省略(./utils 会报 404)

















