AMDvsCMD

AMD:Asynchronous Module Definition (RequireJS)

CMD:Common Module Definition(SeaJS)

AMD CMD
1. 提前执行 延迟执行(类似饿汉模式)
2. 依赖前置 依赖就近
3. 浏览器(加载缓慢,异步load更好) 服务器端
4. 异步模块定义 通用模块定义

AMD

待补充,import-export

CMD

define Function

一个文件就是一个模块,在我们的代码外层,会套上一层CMD规范,这也就是为什么我们可以直接引用require,export,module的原因

1
2
3
define(function(require, exports, module) {
// code
});

单个参数

1
2
3
4
define(factory)
param-->factory:funtion|Object|String
define({ "foo": "bar" });
define('I am a template. My name is {{name}}.');

多个参数define define(id?, deps?, factory)

1
2
3
4
5
define('hello', ['jquery'], function(require, exports, module) {
// code
});
id:String模块标识
deps:Array模块依赖

define.cmd Object

1
2
3
4
if (typeof define === "function" && define.cmd) {
// 有 Sea.js 等 CMD 模块加载器存在
}
//用来判断当前页面是否有CMD模块加载器

require Function

同步加载

1
2
3
4
5
6
7
8
9
define(function(require, exports) {

// 获取模块 a 的接口
var a = require('./a');

// 调用模块 a 的方法
a.doSomething();

});

require.async Function

异步加载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
define(function(require, exports, module) {

// 异步加载一个模块,在加载完成时,执行回调
require.async('./b', function(b) {
b.doSomething();
});

// 异步加载多个模块,在加载完成时,执行回调
require.async(['./c', './d'], function(c, d) {
c.doSomething();
d.doSomething();
});

});

require.resolve

返回解析后的绝对路径

exprots

return Object,对外提供接口

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
define(function(require, exports) {

// 对外提供 foo 属性
exports.foo = 'bar';

// 对外提供 doSomething 方法
exports.doSomething = function() {};

});

retrun可以实现同等效果
define(function(require) {

// 通过 return 直接提供接口
return {
foo: 'bar',
doSomething: function() {}
};

});
以及个人不太喜欢的缩略写法
define({
foo: 'bar',
doSomething: function() {}
});

但以下写法是错误的

1
2
3
4
5
6
7
8
9
define(function(require, exports) {

// 错误用法!!!
exports = {
foo: 'bar',
doSomething: function() {}
};

});

exports 仅仅是 module.exports 的一个引用。在 factory 内部给 exports 重新赋值时,并不会改变 module.exports 的值。因此给 exports 赋值是无效的,不能用来更改模块接口。

我说句简单的话:exports和module.exports,都是地址,指向同一个内容,如果你给exports赋值了一个新对象,他指向的内容就完全变了,和module.exprots就指向不是同一个地方了

module

modeule是一个对象,存储与当前模块相关联的一些属性和方法,默认为{}

module:function

module.id:String模块标识

module.url:String返回绝对路径(默认id=url,除非手写id)

module.dependencies:Array模块依赖

module.export:Object 大部分情况下和exports通用,但如果模块是一个类,就应该直接赋值给module.exports,这样调用就是一个类的构造器,可以直接new实例

1
2
3
4
5
6
7
8
module.exports=new Person();
const p = require(./xxx.js);
p.say();
//or
exports.p = new Person();
const {p} = require(./xxxjs);
p.say();