JavaScript模块规范
CommonJS
Node.js和Webpack采用CommonJS编写,包括:
- 模块引入(require),用于加载模块
- 模块定义(exports),对外的接口,加载模块其实就是加载module.exports属性(Node中每个模块exports即为module.exports,不要对exports重新赋值,只能添加属性)
模块标识(module),在模块内代表当前模块
特点:
独立作用域
- 同步引入
- 首次加载时require时运行,再次加载直接取缓存结果,要再次运行需要清除缓存
require命令
- 加载并执行一个js文件,返回exports属性
- 参数可以为绝对路径、相对路径、文件名,文件名查找顺序node安装目录->当前目录node_modules->逐级向上的node_modules
- require.main === module,可以在模块内判断模块是直接执行(true)还是require加载执行
循环加载
A加载B,B又加载A,那么B加载的将是A已经执行的部分,例如:
1 | // A.js |
AMD
Asynchronous Module Definition,异步模块定义,依赖前置原则,主要用于浏览器,RequireJS 在推广过程中对模块定义的规范化产出
定义模块
语法1
2
3
4
5
6
7
8
9
10
- id,模块标识
- dependencies,依赖的模块的名称数组,依赖前置,先解决依赖才会执行factory方法
- factory,工厂方法,初始化模块需要执行的函数或者对象,函数参数为依赖的模块,为对象时为模块的输出值
### 加载模块
需要引入require.js后使用require方法
```require([dependencies], fucntion(){})
示例
1 | // base.js |
CMD
Common Module Definition,通用模块定义,依赖就近原则,是SeaJS 在推广过程中被广泛认知。
定义模块
语法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
- factory,可以为字符串、对象、函数等
- 为函数时就是模块的构造方法,function(require, exports, module) {}
- 构造方法内require为同步加载,require.async(dependencies, function(){})为异步加载
## UMD
兼容CommonJS和AMD规范
## ES6
- 静态化,ES6在编译时确定依赖关系而不是CommonJS和AMD的运行时,所以引入是不能是表达式
- ES6的模块并不返回一个对象,通过export和import导出和引入
- 提升效果,可以在引入前使用
```javascript
// CommonJS
let { aaa, bbb } = require('math');
// 相当于
let tmp = require('Math');
let aaa = require.aaa;
let bbb = require.bbb;
// ES6
import { aaa, bbb } from 'math';
// aaa, bbb必须和模块中导出的变量同名
// export和import时都可以使用as对变量重命名,使用*表示整个模块
// 模块内使用export default匿名导出,引用时可以自己命名模块
import anyname from 'math';