ES模块需环境支持:Node.js须用.mjs后缀或"type":"module",浏览器script需type="module";export default导入无大括号,named export需大括号;CommonJS与ESM不能直接混用。

ES 模块(ESM)是 JavaScript 官方标准,但 Node.js 和浏览器对 import/export 的支持有细节差异,直接照搬会报错。
Node.js 中必须用 .mjs 后缀或 "type": "module"
Node.js 默认把 .js 文件当 CommonJS 处理,即使写了 export 也会抛出 SyntaxError: Unexpected token 'export'。
- 方案一:文件名改为
index.mjs,然后运行node index.mjs - 方案二:在
package.json里加"type": "module",之后所有.js都按 ESM 解析 - 注意:
require()在 ESM 文件中不可用,也不能混用import和require(会报ERR_REQUIRE_ESM)
export default 和 export 的导入写法不同
导出方式决定导入时是否要加大括号 —— 这是新手最常写错的地方。
-
export default function foo() {}→ 导入时:import foo from './foo.js'(无大括号,名字可任意) -
export function bar() {}或export const x = 1→ 导入时:import { bar, x } from './foo.js'(必须用大括号,且名字要一致) - 想重命名?用
import { bar as myBar } from './foo.js' - 全部导入?
import * as utils from './utils.js',之后用utils.bar()
浏览器中 import 必须加 type="module" 属性
直接在 HTML 里写 不会触发模块解析,import 会报 Uncaught SyntaxError: Cannot use import statement outside a module。
立即学习“Java免费学习笔记(深入)”;
- 正确写法:
- 模块脚本默认是
defer行为(即 DOM 解析完才执行),不阻塞 HTML 渲染 - 路径必须是相对或绝对 URL,不能是纯模块名:
import { foo } from 'lodash'会失败(浏览器不支持 bare import),要用完整路径如https://cdn.skypack.dev/lodash
CommonJS(require)和 ESM 不能直接互通
Node.js 允许在 CommonJS 里 require('./esm-file.js'),但前提是该文件已标记为模块(.mjs 或 "type": "module"),且返回的是一个 Promise(因为 ESM 是异步加载的)。
- CommonJS 中无法直接
require()ESM 文件并拿到同步值;更稳妥的方式是用await import('./esm.js') - ESM 中无法使用
require(),连__dirname和__filename都不存在(得用import.meta.url配合url.fileURLToPath()) - 跨环境兼容?优先选 ESM,再通过打包工具(如 Vite、esbuild)处理兼容性,而不是手动混合两种语法
模块系统不是“写对语法就行”,关键是运行时环境是否真正启用 ESM 解析——后缀、配置、HTML 属性、路径格式,漏掉任何一个都会卡在报错上。











