########### 模块 https://github.com/seajs/seajs/issues/240 #####################
sea.js 专注于前端开发领域里的 JS 模块:
1. 模块是一段 JavaScript 代码,具有统一的基本书写格式。
2. 模块之间通过基本交互规则,能彼此引用,协同工作。
模块定义规范(Module Definition Specification):对[基本书写格式]与[基本交互规则]的清楚描述。
有CommonJS 社区的 Modules 1.1.1 规范、NodeJS 的 Modules 规范、RequireJS 提出的 AMD 规范等等。
sea.js 遵循的是 CMD 规范
########## CMD模块定义规范 https://github.com/seajs/seajs/issues/242 ############
CMD(common Module Definition)。该规范明确了模块的[基本书写格式]和[基本交互规则]。
CMD 规范中,一个模块就是一个文件。
define(factory)
define:是[全局函数],用来定义一个模块
factory:函数、对象或者字符串
define({‘foo‘, ‘bar‘});
define(‘I am a template, My name is {{name}}‘);
↓
factory为函数时,表示[模块的构造方法],可以得到模块向外提供的接口。 factory 方法在执行时,默认会传入三个参数:require、exports 和 module.
define(id?, deps?, factory)
字符串 id 表示模块标识,数组 deps 是模块依赖
define(‘hello‘, [‘jquery‘], function(require, exports, module) {
// 模块代码
});
define.cmd
一个空对象,可用来判定当前页面是否有 CMD 模块加载器
if (typeof define === ‘function‘ && define.cmd) {
// 有 sea.js 等 CMD 模块加载器存在
}
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
require(id)
require 是一个方法,接受[模块标识]作为[唯一参数](参数值必须是字符串直接量。),用来获取模块提供的接口
define(function(require, exports) {
// 获取模块 a 的接口
var a = require(‘./a‘);
// 调用模块 a 的方法
a.doSomething();
});
require.async(id, callback?)
require.async 用来在模块内部[异步加载]模块,在加载完成后执行回调( callback 可选)。 require(id) 是同步往下执行
define(function(require, exports) {
// 异步加载一个模块,在加载完成时,执行回调
require.async(‘./b‘, function(b) {
b.doSomething();
});
// 异步加载多个模块,在加载完成时,执行回调
require.async([‘./c‘, ‘./d‘], function(c, d) {
// 这 function 里的参数要与前面加载模块的顺序一一对应
c.doSomething();
d.doSomething();
});
});
require.resolve(id)
该函数[不会加载函数],只[返回]解析后的[模块绝对路径]。(使用模块系统内部的路径解析机制)
define(function(require, exports) {
console.log(require.resolve(‘./b‘));
// ==> http://localhost/seajsS/quick-start/static/hello/src/b.js
});
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
exports
是一个对象,用来向外提供模块接口
define(function(require, exports) {
// 对外提供 foo 属性
exports.foo = ‘bar‘;
// 对外提供 doSomething 方法
exports.doSomething = function() {};
});
替代exports
使用 return 直接向外提供接口
define(function(require) {
// 通过 return 直接提供接口
return {
foo: ‘bar‘, doSomething: function() {}
};
});
或者是
define(function(require, exports, module) {
// 正确写法
module.exports = {
foo: ‘bar‘, doSomething: function() {}
};
// 错误写法
// 解释:exports 仅仅是 module.exports 的一个引用,给 exports 重新赋值时,并不会改变 module.exports 的值,OK?
exports = {
foo: ‘bar‘, doSomething: function() {}
};
});
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
module
是一个对象,存储了与当前模块相关联的一些属性和方法
module.id
模块的唯一标识。define 的第一个参数就是模块标识
define(‘module_id‘, [], function(require, exports, module) {
// 模块代码
});
module.uri
返回模块的绝对路径(根据模块系统的路径解析规则)。
define(function(require, exports, module) {
console.log(module.uri);
// ==> http://localhost/seajsS/quick-start/static/hello/src/main.js
});
没有在 define 中手写 id 参数时,module.id 的值就是 module.uri,两者完全相同
注意:而require.resolve(id) 是使用模块系统内部的路径解析机制的
module.dependencies Array
表示当前模块的依赖
module.exports Object
当前模块对外提供的接口
传给 factory 构造方法的 exports 参数是 module.exports 对象的一个引用。只通过 exports 参数来提供接口,有时无法满足开发者的所有需求。 比如当[模块的接口是某个类的实例]时,需要通过 module.exports 来实现
define(function(require, exports, module) {
// exports 是 module.exports 的一个引用
console.log(module.exports === exports); // true
// 重新给 module.exports 赋值(模块的接口是某个类的实例)
module.exports = new SomeClass();
// exports 不再等于 module.exports
console.log(module.exports === exports); // false
});
这就是 CMD 模块定义规范的所有内容。经常使用的 API 只有 define, require, require.async, exports, module.exports 这五个。其他 API 有个印象就好,在需要时再来查文档,不用刻意去记。
原文:http://www.cnblogs.com/zhangbao/p/4422514.html