JavaScript 模块系统全景解析
JavaScript 模块系统全景解析
JavaScript 最初是为浏览器设计的脚本语言,没有原生模块系统。在社区和平台演化过程中,逐步发展出多个模块系统来解决不同阶段的问题。本文汇总主流模块系统的出现时间、特征、解决的问题、适用场景,并提供结构对比图。
🧱 模块系统发展历程
模块系统 | 出现时间 | 特点 | 解决的问题 | 适用场景 |
---|---|---|---|---|
Global 变量 | ~1995 | 没有模块系统 | 所有 JS 代码在同一作用域,变量冲突严重 | 最早期网页脚本(无组织) |
CommonJS (CJS) | 2009 | 同步加载、require() | Node.js 需要模块化支持,解决服务器端代码组织 | Node.js 应用(默认模块系统) |
AMD | 2010 | 异步加载、浏览器为主 | 浏览器中需要非阻塞加载模块,RequireJS 推动 | 浏览器项目、早期工程化(已淘汰) |
UMD | 2011 | 通用模块包装器 | 同时兼容 CommonJS、AMD 和全局变量 | JS 库开发者需要“通用构建”支持(如 jQuery 插件) |
ESM(ES Modules) | 2015(标准) 2017+(浏览器支持) 2020+(Node.js 完善支持) | 原生支持、静态分析、tree-shaking、异步模块 | 统一前后端模块系统、构建友好 | 浏览器 / Node.js / 构建工具统一模块化 |
SystemJS | 2014 | 动态模块加载器 | 为了模拟 ESM 语法做 polyfill,适配旧环境 | 插件系统、兼容层(使用逐渐减少) |
🧩 模块系统对比图(结构)
┌─────────────┐ ┌────────────┐│ Global 变量 │────────▶│ 模块污染问题 │└─────────────┘ └────────────┘│ ▲▼ │┌─────────────┐ ┌──────────────────┐│ CommonJS │────────▶│ Node.js 后端模块 │└─────────────┘ └──────────────────┘│ ▲▼ │┌─────────────┐ ┌─────────────┐│ AMD │ │ UMD │──┐└─────────────┘ └─────────────┘ ││ │ ▼▼ └──────▶ 前端库兼容发布┌────────────────────────┐│ SystemJS(过渡) │└────────────────────────┘│▼┌────────────────────────┐│ ES Modules(ESM) │└────────────────────────┘
✅ 模块系统选型建议
场景 | 推荐模块系统 |
---|---|
Node.js 应用(旧) | CommonJS |
新的 Web 应用 | ESM |
库/插件要兼容多个平台 | UMD(构建产物) + 源码用 ESM |
插件系统/动态加载需求 | SystemJS / import() 动态模块 |
构建工具(Rollup, Vite) | ESM(原生支持 tree-shaking) |
📝 总结
现代 JavaScript 开发中,ESM 是推荐的统一模块标准,除非你在维护老旧项目或需要兼容特定环境。了解各模块系统的历史与特征有助于做出更合适的架构决策,也利于在库开发和构建配置中避免不兼容问题。
如需进一步了解各系统的兼容性或迁移方案,可以继续查看:MDN ES Module