ESModule 不允许同名导出变量,解析阶段即报 SyntaxError;不同模块可导出同名变量,导入时用 as 重命名解决冲突;默认导出与命名导出可共存,但命名不能为保留字;动态导出不支持,需通过对象导出或拆分模块规避。

ESModule 不允许同名导出变量,一旦出现同名 export,语法解析阶段就会报错,根本不会等到运行时。
同名导出直接报错
JavaScript 引擎在解析模块时会检查导出声明。如果一个模块中出现两个相同名称的命名导出(比如两次 export const foo = 1; 或 export { foo }; 指向同一个名字),会立即抛出 SyntaxError:
export const a = 1;-
export const a = 2;→ ❌ 报错:Identifier 'a' has already been declared -
const a = 1; export { a }; const a = 2; export { a };→ ❌ 同样报错(重复声明)
重命名导入可解决同名冲突(跨模块)
不同模块导出同名变量是允许的;冲突发生在**导入时**。此时用 as 重命名即可区分:
import { foo as fooFromA } from './a.js';import { foo as fooFromB } from './b.js';- 这样
fooFromA和fooFromB就是两个独立变量,互不干扰
默认导出 + 命名导出可共存,但不能同名
一个模块可以同时有 export default 和命名导出,但命名导出的名称不能和默认导出的绑定名冲突(注意:默认导出本身没有“名字”,但你在导入时指定的局部名不能和已有的命名导出重名):
立即学习“Java免费学习笔记(深入)”;
export default function() {};-
export const default = 42;→ ❌ 错误:保留字不能作导出名 -
export const name = 'x';✅ 可以 -
import theDefault, { name } from './m.js';✅ 正常
动态导出或条件导出需提前规划
ESM 是静态编译的,不支持运行时决定导出什么。所以不能靠 if 动态改导出名。若逻辑上需要“可选导出”,常见做法是:
- 统一导出一个对象,把可能冲突的值作为属性:
export const utils = { foo: ..., bar: ... }; - 拆分成多个细粒度模块,按需导入:
import { foo } from './utils/foo.js'; - 用构建工具(如 Rollup、Vite)做导出别名或 re-export 处理
本质上,ESModule 的设计就是靠静态可分析性来杜绝命名冲突——导出名必须唯一且确定,冲突在写代码时就暴露,而不是留到集成阶段才发现。


















