JavaScript模块化是控制依赖、避免污染、支持按需加载的底层机制;浏览器需用启用ESM,Node.js需.mjs扩展名或"type":"module"声明。

JavaScript 模块化不是“加个 import 就完事”的语法糖,而是控制代码依赖关系、避免全局污染、支持按需加载的底层机制。现代浏览器和 Node.js 默认启用 ES 模块(ESM),但行为不完全一致——直接写 import/export 可能报错,关键在环境和加载方式。
为什么 import 在 HTML 里直接用会报 Uncaught SyntaxError: Cannot use import statement outside a module
浏览器默认把 当作传统脚本(script),不是模块(module)。必须显式声明:
-
才启用 ESM 解析,此时import/export才合法 -
type="module"脚本自动启用严格模式、顶层this为undefined、支持顶层await - 模块路径必须是相对路径(
./util.js)、绝对路径(/js/main.js)或完整 URL;不能省略扩展名,也不能用纯名字(import {foo} from 'util'❌)
export 的三种写法差异:命名导出、默认导出、重导出
导出方式决定导入时怎么解构,也影响 Tree-shaking 效果:
-
命名导出(named export):可导出多个,导入时必须用大括号
{},且名称必须一致export const PI = 3.14;export function add(a, b) { return a + b; }
→ 导入:import { PI, add } from './math.js'; -
默认导出(default export):每个模块最多一个,导入时可自定义名,无需大括号
export default function calc() { ... }
→ 导入:import calc from './calc.js';或import myCalc from './calc.js'; -
重导出(re-export):不执行,只透传,常用于聚合模块
export { PI as PI_VALUE } from './math.js';export * as utils from './utils.js';(注意:这不会透传 default)
Node.js 中 import 报 ERR_REQUIRE_ESM 怎么办
Node.js 默认用 CommonJS(require()),ESM 需满足两个条件之一:
立即学习“Java免费学习笔记(深入)”;
- 文件扩展名为
.mjs(优先级最高,无视package.json) - 或
package.json中声明"type": "module"(整个包走 ESM) - 若仍要混用,可用
createRequire(import.meta.url)在 ESM 文件里调require(),但仅限加载 CommonJS 模块 - 注意:
__dirname和__filename在 ESM 中不可用,改用fileURLToPath(import.meta.url)+path.dirname()
模块路径解析、循环依赖处理、动态 import() 的加载时机,这些细节在真实项目里比语法更常引发问题。别只盯着 export default 写得顺不顺——先确认运行时把它当模块加载了,再谈导出逻辑。











