cmd的全称是Common Module Definition,即通用模块定义,其提供了模块定义和按需加载执行模块。该规范明确了模块的基本书写格式和基本的交互规则。
在CMD规范中,一个文件就是一个模块,使用define来进行模块:
代码语言:javascript复制define(factory)
这里的define是一个全局函数,用来定义模块,这里的factory参数既可以是函数,又可以是字符串或对象。如果参数是字符串或对象时,表示该模块的接口就是是该对象或字符串:
代码语言:javascript复制define({'website':'oecom'});
define('这里是OECOM');
当factory为函数时,此函数就是模块的构造方法,该函数默认为提供三个参数:require,exports,module
代码语言:javascript复制define(function(require,exports,module){
})
require
同步加载
require参数也是一个方法,接收的参数为模块标识,其实就是需要加载模块的相对路径,作用就是加载其他模块。
代码语言:javascript复制define(function(require,exports,module){
var a = require('./a');
a.out();//假设模块a有out方法。
})
异步加载
直接使用require加载属于是同步加载,require提供了async方法来在模块内部进行也不加载模块,并在加载完成以后执行指定的回调函数。
代码语言:javascript复制define(function(require,exports,module){
require.async('./a',function(a){
a.doSomething()
})
require.async(['./c','./b'],function(c,b){
c.doSomething()
b.doSomething()
})
})
注意:require
是同步往下执行,require.async
则是异步回调执行。require.async
一般用来加载可延迟异步加载的模块。
获取模块路径
require.resolve使用模块系统内部的路径解析机制来解析并返回模块路径。该函数不会加载模块,只返回解析后的绝对路径。
代码语言:javascript复制define(function(require,exports){
console.log(require.resolve('./a'));
//http://example.com/path/to/a.js
})
该方法一般用于插件环境或需要动态拼接模块路径的场景。
exports
exports是一个用来想外接提供模块接口的对象
代码语言:javascript复制define(function(require,exports){
var name = 10;
exports.name = name;
exports.out = function(){
console.log("输出内容")
}
})
当加载的时候就可以直接使用下面的方式了:
代码语言:javascript复制define(function(require,exports,module){
var a = require('./a');
a.out();//输出内容
console.log(a.name);//10
})
当然导出模块还可以直接使用return的方式
代码语言:javascript复制define(function(require){
return{
name:10,
out:function(){
console.log("输出内容")
}
}
})
但是千万不要写成
代码语言:javascript复制 exports = {
name:10,
out:function(){
console.log("输出内容")
}
};
但是可以用module.exports的形式来写:
代码语言:javascript复制define(function(require,exports,module){
module.exports = {
name:10,
out:function(){
console.log("输出内容")
}
}
})
提示:exports
仅仅是 module.exports
的一个引用。在 factory
内部给 exports
重新赋值时,并不会改变 module.exports
的值。因此给 exports
赋值是无效的,不能用来更改模块接口。
还有一点就是导出模块不要写在回调函数里,导出是需要同步执行,否则导入是会导入失败。