Module
1. 介绍
模块(Module)是能够单独命名并独立地完成一定功能的程序语句的集合(即程序代码和数据结构的集合体)。
两个基本特征:外部特征和内部特征。
为什么需要模块
如果没有模块化,业务增长后代码会越来越难以维护(命名冲突、文件依赖混乱、加载顺序不可控)。因此需要一种将 JavaScript 程序模块化的机制。
2. AMD/CommonJS 与 Module 的区别
ES6 在语言标准的层面上实现了 Module,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。
特点
- CommonJS 和 AMD 模块都只能在运行时确定依赖(CommonJS 模块就是对象,输入时必须查找对象属性)。
- ES6 Module 设计思想是尽量静态化,编译时就能确定模块的依赖关系和输入输出变量,支持 tree-shaking。
// CommonJS
let { stat, exists, readfile } = require('fs');
// 等同于
let _fs = require('fs');
let stat = _fs.stat, exists = _fs.exists, readfile = _fs.readfile;
// ES6
import { stat, exists, readFile } from 'fs';
上述 ES6 代码只加载 3 个方法,其他方法不加载,编译时即可完成模块加载;编译时加载使静态分析成为可能(包括 TypeScript)。
3. 用法:export / import
- 在编译阶段,
import会提升到模块头部首先执行。 - ES6 允许在一个模块中先输入后输出同一个模块:
export { foo, bar } from 'my_module';
动态加载
允许仅在需要时动态加载模块,不必预先加载所有模块,有明显性能优势。import() 作为函数调用,参数为模块路径,返回一个 Promise。
import('/modules/myModule.mjs').then((module) => {
// Do something with the module.
});
补充:ES Module 与 CommonJS 的核心区别:
| 维度 | ES Module | CommonJS |
|---|---|---|
| 加载时机 | 编译时(静态) | 运行时 |
| 输出 | 值的引用(实时绑定) | 值的拷贝 |
| Tree-shaking | 支持 | 不支持 |
| 浏览器原生 | 是(type="module") | 否(需打包) |
| 关键字 | import / export | require / module.exports |
来源整理自:我的有道云笔记



