ECMAScript模块模式
区分模块语义、宿主解析、包入口和构建转换,并解释它们如何共同决定模块能否运行。
#dev
#synthesis
#growing
#javascript
#ecmascript
[!info] related notes
- 所属 MOC: ECMAScript MOC, JavaScript的工程化与运行时
- 原子概念: ES6 模块导入导出, commonjs-amd-umd, HTML 中的 JS 脚本
- 宿主环境: 浏览器中的 JavaScript, Node.js 中的 JavaScript
- Node 配置: package-json
ECMAScript模块模式
本页解释模块语义、宿主加载和工程配置如何共同工作;阅读入口见 JavaScript 模块与工程化 MOC。
模块化到底在解决什么
当代码开始拆成多个文件时,会立刻遇到:
- 变量污染
- 依赖关系不透明
- 加载顺序难管理
- 宿主环境解析规则不同
模块化的本质,就是把“拆文件”和“依赖关系”变成明确规则。
这组主题的四层结构
1. 语言层:ESM
- ES6 模块导入导出
- 这是现代 JavaScript 的主线模块语法
2. 生态格式:CommonJS / AMD / UMD
- CommonJS 仍用于 Node 包与项目,不能仅按“过时格式”处理
- commonjs-amd-umd 比较 CJS、AMD 与 UMD 包装的职责
3. 宿主加载层
- HTML 中的 JS 脚本 解释浏览器里的脚本标签与模块脚本
- 浏览器中的 JavaScript / Node.js 中的 JavaScript 解释不同运行时怎样看待模块
4. 项目层
- JavaScript的工程化与运行时 负责把模块化放回真实项目上下文
一条具体关系路径
以 Node ESM 中 import value from "some-package" 为例:宿主先按包入口与条件导出等规则解析目标,再按扩展名和包配置判断模块格式,随后加载、建立绑定并求值。目标若为 CJS,便涉及 Node 的互操作规则;静态语法本身不能保证导入成功。
浏览器原生 ESM 不直接读取 npm 的 package.json 来解析裸包名,通常需要 import map 或可解析的 URL;构建工具也可以预先解析、转换和打包。因此“打包后能运行”不能证明源文件在 Node 或浏览器原生环境同样能运行。
推荐阅读顺序
一句话对比
- 学现代开发,先抓 ESM
- 学旧项目与历史演进,补 CommonJS / AMD / UMD
- 学实际加载与运行边界,回到浏览器和 Node.js 笔记